Erlang Postgres Connection Pool with Episcina

Almost exactly a year ago I was looking to merge the many forks of Will Glozer's Postgres client for use in a project at Heroku. Instead Semiocast released their client, I gave it a try and never looked back. (But note that David Welton, a braver person than me, is working on merging the forks of epgsql at this time). I found Semiocast's client to be clean, stable and I liked the interface better.

At the same time I was in the need of a connection pooler. Many have relied on poolboy or pooler for this purpose but neither actually fits the use case of connection pooling that well. Luckily Eric and Jordan were in the need at the same time and created the Erlware project episcina, which they based off of Joseph Wecker's fork of Will Glozer's epgsql pool. Episcina differs in that it is purely for connection pooling, it is not for pooling workers and it is not for pooling generic processes.

Here I'll show how I combined the two in a simple example.

To start we have a sys.config file to configure episcina:

{episcina, [{pools, [{primary,  
                        [{size, 10},                          
                         {timeout, 10000},  
                         {connect_provider, {pp_db, open,  
                                             [[{host, "localhost"}  
                                              ,{database, "postgres_pool"}  
                                              ,{port, 5432}  
                                              ,{user, "postgres"}  
                                              ,{password, "password"}]]}},  
                         {close_provider, {pp_db, close, []}}]}]  

A key thing to note here is the connect and close providers are function calls to modules within the project and not the Postgres client. Episcina requires a return value of {ok, pid()} and the Semiocast client returns {pgsql_connection, pid()}, so we wrap the connection calls to get around that:

-spec get_connection(atom()) -> {pgsql_connection, pid()} | {error, timeout}.  
get_connection(Pool) ->  
    case episcina:get_connection(Pool) of  
        {ok, Pid} ->  
            {pgsql_connection, Pid};  
        {error, timeout} ->  
            {error, timeout}  

-spec return_connection(atom(), {pgsql_connection, pid()}) -> ok.  
return_connection(Pool, {pgsql_connection, Pid}) ->  
    episcina:return_connection(Pool, Pid).  

-spec open(list()) -> {ok, pid()}.  
open(DBArgs) ->  
    {pgsql_connection, Pid} = pgsql_connection:open(DBArgs),  
    {ok, Pid}.  

-spec close(pid()) -> ok.  
close(Pid) ->  
    pgsql_connection:close({pgsql_connection, Pid}).  

And here is the query function to get a connection and return it to the pool after completion:

-spec query(string()) -> tuple().  
query(Query) ->  
    C = get_connection(primary),  
        pgsql_connection:simple_query(Query, [], infinity, C)  
        return_connection(primary, C)  

This example project uses relx to build a release which will start episcina on boot:

{release, {postgres_pool, "0.0.1"},  

{sys_config, "./config/sys.config"}.  
{dev_mode, true}.  

{include_erts, true}.  
{extended_start_script, true}.  

Boot the release to an interactive shell and play around:

λ _rel/bin/postgres_pool console  
([email protected])1> pp_db:query("SELECT 1").  

Some Thoughts on Go and Erlang

UPDATE: I'm seeing that I did not make the point of this post clear. I am not saying Go is wrong or should change because it isn't like Erlang. What I am attempting to show is the choices Go made that make it not an alternative to Erlang for backends where availability and low latency for high numbers of concurrent requests is a requirement. And notice I'm not writing this about a language like Julia. I have heard Go pitched as an alternative to Erlang for not only new projects but replacing old. No one would say the same for Julia, but Go and Node.js are seen by some as friendlier alternatives. And no, Erlang isn't the solution for everything! But this is specifically about where Erlang is appropriate and Go is lacking.

I'm going to attempt to leave out my subjective opinions for disliking parts of Go, such as syntax or lack of pattern matching, and explain objective reasons for the language and runtime not being fit for certain types of systems. But I'll start with the good.

Where Go Shines


As Rob Pike wrote, his biggest surprise was Go is mostly gaining developers from Python and Ruby, not C++. To me this trend has been great to see. No more slow clients installed through pip or gems! (Though for some reason Node.js for clients is growing, wtf Keybase?)

Go provides developers with a fast and easy to use high level, statically typed language with garbage collection and concurrency primitives. It would be great for C++ developers to move to Go as well, the programs that crash constantly on my machine are proprietary C++ that love to misuse memory -- Hipchat and Spotify. But Rob Pike pointed out that the C++ developers don't want the simplified, yet powerful, world of Go. Ruby and Python developers, rightly, do.


Getting up and going with building executables depending on third party libraries can be done easily without depending on third party tools, it all comes with Go. While the tools aren't perfect, there are tools to fill in some gaps like Godep, it is still a huge win for the language.

Where Go Falls Short

Some of Go's design decisions are detrimental when it comes to writing low-latency fault-tolerant systems.


Yes, I listed concurrency primitives as a plus in the first section. It is in the case of replacing Ruby or Python or C++ for clients. But when it comes to complex backends that need to be fault-tolerant Go is as broken as any other language with shared state.

Pre-emptive Scheduling

Here Go has gotten much better. Go's pre-emptive scheduling was done on syscalls but now pre-emption is done when a goroutine checks the stack, which it does on every function call, and this may be marked to fail (causing pre-emption) if the goroutine has been running for longer than some time period. While this is an improvement it still lags behind Erlang's reduction counting and newly added dirty schedulers for improved integration with C.

Garbage Collection

In Go garbage collection is global mark and sweep. This pauses all goroutines during the sweep and this is terrible for latency. Again, low latency is hard, the more the runtime can do for you the better.

Error Handling

This isn't just about having no exceptions and the use of checking if a second return value is nil. Goroutines have no identity which means Go lacks the ability to link or monitor goroutines. No linking (instead using panic and defer) and no process isolation means you can not fall back on crashing and restarting in a stable state. There will be bugs in production and a lot of those bugs will be Heisenbugs, so being able to layout processes, isolated from each other but linked based on their dependencies, is key for fault tolerance.

And on top of these major omissions in dealing with faults Go has nil. How in 2014 this is considered OK I haven't wrapped my mind around yet. I'll just leave it at that, with a befuddled look.


Not having a REPL is annoying for development, but no remote shell for running systems is a deal breaker. Erlang has impressive tracing capabilities and tools built on those capabilities like recon_trace. Erlang's introspection greatly improves development as well as maintenance of complex running systems.

Static Linking

Yes, another thing that was also in the positives but becomes a negative when used in systems that are expected to be long running. While having no linking does means slower execution it gives Erlang advantages in the case of code replacement on running systems. It is important to note that due to Erlang's scheduling and garbage collecting strategies many of these speed tradeoffs do not mean Erlang will be slower than an implementation in another language, especially if the Erlang implementation is the only one still running.

Code Organization

The OTP framework provides libraries for common patterns. OTP not only means less code to write and better abstractions but also improves readability. Following the OTP standards with applications, supervisors and workers (genserver, genfsm, gen_event) means a developer new to the program is able to work down through the tree of processes and how they interact. Go's channels, unidentifiable goroutines and lack of patterns to separate goroutines into separate modules leads to much harder code to reason about.

Can or Even Should Go Change?

Erlang has been around for decades and Go is the new kid on the block, so can Go improve in these areas? Some, yes, but most of it can not because of the choices made in the design of the language which were not fault tolerance and low latency.

This doesn't mean Go is "bad" or "wrong". It simply makes different choices and thus is better suited for different problems than a language like Erlang.

How to use Vim for Erlang Development

vim editor logo

This post sponsored by ErlangCamp 2013 in Nashville which was epic!

You are about to learn to use Vim as your editor for Erlang development. You will learn how to install and use a variety of really powerful Vim plugins to make Erlang dev with Vim smooth and satisfying!

I have been developing Erlang now for about 13 years, many of them full time and even wrote a book on Erlang: Erlang & OTP in Action. I have loved every minute of it but there was always one thing that made me sad, probably makes you sad too - Emacs. Emacs is the de-facto editor for Erlang. The emacs mode included with the Erlang distro is quite wonderful. The fact still remains, Emacs, we do not like it. ctrl ~, ctrl x ctrl f etc... Nope!

Setting up Vim for Erlang

Let's get started setting up Vim for Erlang development. The first thing we need to do is setup pathogen so that installing subsequent packages is really simple. The first thing to do is create the directory $HOME/.vim/autoload. Download pathogen.vim from here and place it into this directory. Now add the following 2 commands to your $HOME/.vimrc file.

call pathogen#infect()
call pathogen#helptags()

At this point pathogen will install and generate help documentation for any plugin you place into the $HOME/.vim/bundle directory - which you should of course create.

With this created now we are ready to start installing plugins to make your life easier. Try these on for size by cloning these git repos directly into the $HOME/.vim/bundle directory. They will simply work next time you start vim.

[**vimerl.vim**](, autocomplete and more for Erlang
[**ctrlp.vim**]( p and open a powerful fuzzy file finder. Makes navigating file trees a thing of the past.
[**NERDTree**]( file tree navigator right in vim - don't use it much since I installed ctrlp though.
[**NERDTree Tabs**]( the NERDTree file finder to all tabs you have open in vim.

Before we get into basics on how to use all these plugins to create Erlang magic I want to show you two bonus tricks I really love. First, get a better color scheme. To do this create the directory $HOME/.vim/colors and find yourself a slick color scheme to drop into it. I recommend vividchalk.vim by TPope.

Pro Tip

For dropbox or other file sync users keep all your vim installs in sync easily like so; take your .vim and your .vimrc and move them into your Dropbox directory. Then run:


ln -s ~/Dropbox/.vim ~/.vim

ln -s ~/Dropbox/.vimrc ~/.vimrc


Now all your machines vim installs will run just the same. If you have compatibility problems on any one, well then just skip this for that machine.

Ok, so now on to how to use these plugins for Erlang/Vim greatness.

How to Use our Vim Plugins for Erlang Dev

I am going to use the source for Erlware Commons as an example. So I clone it first and then change into the erlware_commons directory and run vim. Now lets say I know what file I want to update, specifically the "ecdate.erl" file. The first thing I do is type p and then start typing ecdate.erl.

[No Name] [TYPE= unix] [0/1 (100%)]                                               
> test/ec_dictionary_proper.erl  
> src/ec_dictionary.erl  
> src/ec_date.erl                                                                 
 prt  path  ={ files }=  >> ec_da  

You can see that as I start typing and get to "ecda" ctrlp has already displayed a narrowed down list of files in the directory tree under where I have opened vim that match. The file on the bottom ecdate.erl is the one selected and so just pressing enter here will open it. If I wanted to select "test/ecdictionaryproper.erl" then I could simply press the up arrow and select it or keep typing until it was the only selection.

Now, what if I don't know what file I want to select? This is where NERDTree comes into play. Run :NERDTree and you will pop open the file browser. Like this:

  Press ? for help             |  
.. (up a dir)                  |~                                                 
▸ doc/                         |~                                                 
▸ priv/                        |~                                                 
▸ src/                         |~                                                 
▸ test/                        |~                                                        |~                                                 
  COPYING                      |~                                                 
  Makefile                     |~                                                              |~                                                 
  rebar.config                 |~                                                 
  rebar.config.script          |~                                                 
~                              |~                                                 
~                              |~                                                 
~                              |~                                                                                                                                         

Here we can see the directory tree for Erlware Commons. Each of the directories can be easily selected and expanded. Individual files can be selected and opened. There are a variety of ways to open a file. Below are the most common:

  • &lt;enter&gt; will open the file in the right pane
  • T will open in a new tab within vim and keep focus in NERDTree
  • t will open in a new tab and bring focus to the new tab

IF you want to see the NERDTree browser in all your tabs use :NERDTreeTabsToggle to toggle it on and off. It will be the exact same NERDTree in the exact same state and cursor position on all tabs - nice! Once you are focused on the code in a given tab and you want to jump back to the left and into the NERDTree pane use &lt;ctrl&gt; ww

Once you have a load of tabs open you need to switch between then and to do this you need only two commands:

  • gt will goto the next tab the next tab
  • gT will goto the previous tab

Pro Tip

Map the tab commands and the NERDTreeTabsToggle command by adding the following to your vimrc.


map <C-t> :tabn<Enter>

map <C-n> :tabnew<Enter>

map nt :NERDTreeTabsToggle<Enter>


Ok, now on to editing Erlang with vimerl.

Editing with vimerl

This is not going to be an exhaustive list of vimerl editing commands but just a few of the goodies. The 20% you will use 80% of the time.


vimerl will auto-indent for you as you type. But if you come across a line that you want to indent try typing ==. Lets say you want to indent a block of code. Simple, mark the line that starts the block with ma then go to the end of the block and tell vimerl to indent to the mark as such: ='a. Now if your whole file is a mess then try gg to go to the beginning of your file and then =G to indent all the way to the end. You can do this all in one step as in gg=G.

Code Completion

ctrl-x ctrl-o after typing a module name and a : will cause vimerl to suggest function names for you. It does this by searching the .beam and .erl files in the erlang code path (code:get_path() to see what they are) as well as looking at your rebar deps_dir if you are using rebar.config as part of your project.


This is the feature that I loved most about the emacs mode for Erlang, well this and the auto indenting (most of the time, the fun() indenting still feels like a kick in the teeth). Here is a list of the most useful skeletons and the commands to generate them from within vimerl.

  • :ErlangApplication generate the skeleton for an OTP application behaviour.
  • :ErlangSupervisor generate the skeleton for an OTP supervisor behaviour.
  • :ErlangGen[Server|Fsm|Event] skeletons for gen server, fsm and event - yay!

Brilliant isn't it. Before I let you go there is one more invaluable command you should know about which is :help vimerl which will give you a list of all the other useful commands you may want to use. Remember to get it working be sure to add call pathogen#helptags() to the top of your .vimrc file. Goodbye Emacs, welcome back old friend Vim.

Follow me on twitter @martinjlogan


Universal Makefile for Erlang Projects That Use Rebar

This post sponsored by ErlangCamp 2013 in Nashville and Amsterdam

At this point in the game nearly every Erlang project uses Rebar. The problem with that is that Rebar's approach to the command line and command dependency chaining is leaves a lot to be desired. You tend to end up typing the same command with the same options list over and over again during the course of your work. Because of the poor dependency chaining you often must retype the same sequence of commands as well. Finally, there are certain things (like Dialyzer support) that Rebar does not support.

In our Erlware projects, we want a consistent and recognizable entry point into the build process. For that reason we tend to treat Rebar as a low level tool and drive it and the other build tools I mentioned with a Makefile. That makes it far easier for us, as developers, to chain rules as needed and create additional rules that add features to the build system. This allows us to integrate other tools seamlessly into the build experience. At Erlware, we have developed a pretty standard Makefile that can be used with little or no changes from project to project. You can find the whole of that Makefile here. However, I will work my way through a few parts of it explaining so you understand what is going on and can make changes relevant to your project.

The main targets this Makefile supports are as follows:

  • deps: Pull the project dependencies (called automatically as needed)
  • update-reps: Update the dependencies (never called automatically)
  • compile: Compiles the project
  • doc: Builds the edoc documentation
  • test: Compiles the code and runs the tests (designed to be called by a human)
  • dialyzer: Build the dependency PLT and run dialyzer on the project
  • typer: Run Typer on the project
  • shell: Bring up an Erlang shell with all the dependencies already loaded and unit tests compiled and available.
  • pdf: Turn your into a pdf using pandoc (pretty useful at times, but completely optional)
  • clean: Delete the build output files
  • distclean: Remove the build output files as well as the project PLT file and all the dependencies
  • rebuild: Do a dist clean, rebuild everything from scratch and run both the tests and dialyzer
    Now that we have an idea of the targets available lets work through the major points of the Makefile.

Defining Variables

ERLFLAGS= -pa $(CURDIR)/.eunit -pa $(CURDIR)/ebin -pa $(CURDIR)/deps/*/ebin  

DEPS=erts kernel stdlib  

At the top of the make file a few variables that are set. For the most part you don't ever have to touch any of these with the exception of DEPS. The DEPS variable provides a list of dependent applications that are used by Dialyzer to build the dependency PLT file. The others are ERLFLAGS, which is used by the shell command to correctly make your code available in the shell, and DEPS_PLT, which points to the location where the project PLT file will be located.

PLT Files and Dialyzer

    @echo Building local plt at $(DEPS_PLT)  
    dialyzer --output_plt $(DEPS_PLT) --build_plt \  
       --apps $(DEPS) -r deps  

dialyzer: $(DEPS_PLT)  
    dialyzer --fullpath --plt $(DEPS_PLT) -Wrace_conditions -r ./ebin  

This is how the Dialyzer command is run. The main things to notice here are that a PLT file specific to the project is built using the dependencies that you described at the top of the file in the DEPS variable. Building a per project PLT solves a raft of potential problems but has the downside that the first run of Dialyzer or the first run after a rebuild can take several minutes as it analyzes all of the dependencies to build the PLT file.


Rebuilding is basically a completely clean rebuild and test of the system. You should run this code before you submit a PR or share code with your peers. It basically tries to ensure that you have not forgotten or left off anything that is needed.


You can, quite literally, drop this makefile into your project and use it today with only some very minor modification to the DEPS variable. If you are not already using something like this in your project I encourage you to add this Makefile now. It will save you a lot of tedious typing and make your build process much clearer to your users.


There are a few alternatives to this approach out there. These are quite good if somewhat more complex.