top | item 27682432

An Elixir adoption success story

268 points| lucis | 4 years ago |thegreatcodeadventure.com | reply

200 comments

order
[+] eric4smith|4 years ago|reply
We use elixir 24/7 on all projects. All the new programmers that ever worked with us never knew Elixir in the first place.

And all of them picked it up in a couple of weeks to a level where they could start making changes to code.

I think we are overestimating the amount of time it takes to learn a new language.

The hardest thing to grok with FP is immutable data.

Once you get past that, you're rolling.

But the speed and concurrency is no laughing matter. Miles and miles and miles ahead of ruby, python, etc in that matter.

Task.start(...)

Spin off a background process from a web request where you don't care to get back something.

Basically eliminate Redis or caching.

Just need Postgresql/Mysql.

If you're wild eyed you can use Mnesia without the databases.

Run jobs across a cluster sanely with a good job library that only needs Postgresql.

The story goes on and on. Unless you have tons and tons invested into what you're doing right now, it makes a lot of sense to start to spin up things on the edge of your monolith or SOA with Elixir.

New projects should be started with Elixir.

The idea that it's "hard to find programmers" -- does not really stand up. Because anyone who can't grok a new programming language in a short time, is not really a good programmer.

[+] ashton314|4 years ago|reply
> The idea that it's "hard to find programmers" -- does not really stand up. Because anyone who can't grok a new programming language in a short time, is not really a good programmer.

This this THIS! I have a profound philosophical disagreement with CS professors (usually professors who retired from industry into academia) who think that part of the job of the CS curriculum is to equip students with a language and think that learning multiple languages will dilute their focus or some bull crap like that. Learning new languages is not hard! It is much better to learn how to learn new languages, than it is to learn one language really really well. Learning multiple languages will give you the mental tools to use other languages to their fullest extent.

[+] tiffanyh|4 years ago|reply
So many people talk Erlang / Elixir insane concurrency … but I’m struggling to reconcile the talk with what I find in stress testing and benchmarks results.

Can you comment on why so many benchmarks show Erlang / Elixir performing significantly worse than other languages like Go.

https://stressgrid.com/blog/webserver_benchmark/

https://stressgrid.com/blog/cowboy_performance/

https://www.techempower.com/benchmarks/

EDIT: why the downvotes? I’d rather you post a comment to me so we can have a health dialogue.

[+] devoutsalsa|4 years ago|reply
> The hardest thing to grok with FP is immutable data.

A lack of understanding how concurrency works can really screw you up in Elixir.

> Task.start(...)

I almost never use task, because I like certainty. I've been bitten too badly by people using it who didn't understand it. I don't like having to explain `Enum.each(tasks, &Task.start/1 )` is going to screw up your order of operations to someone who doesn't get it.

> Basically eliminate Redis or caching.

It's easy to start off thinking that, but then you can end up spending a lot of time maintaining subpar libraries you've written in-house that don't have the nicer features of the thing you replaced. Also, caching can turn into quite the memory hog.

> Run jobs across a cluster sanely with a good job library that only needs Postgresql.

It's all fun & games until you have to undo everything so you can containerize the apps.

> If you're wild eyed you can use Mnesia without the databases.

I've used DETS & hate it quite a bit, I really don't want to be married to Mnesia.

> New projects should be started with Elixir.

I love Elixir, but I wouldn't use it for everything, and it's got a lot of sharp edges that can get you into a lot of trouble.

[+] derefr|4 years ago|reply
> But the speed and concurrency is no laughing matter. Miles and miles and miles ahead of ruby, python, etc in that matter.

People always make this comparison, which I feel is a bit weak/unconvincing. It's pretty easy to beat Ruby or Python in concurrency; most language runtimes do it.

Something most people might not realize is that Erlang/BEAM is miles ahead of even Java/the JVM, when it comes to operationalizing its concurrency — that is, building services that are robust in the face of heterogeneous workloads and misbehaving clients.

Ever tried to build a RESTful web service, that performs unpredictable-runtime tasks in response to user requests, but which budgets that runtime such that requests are hard-killed (and their resources freed) after a deadline, and/or if the client closes their TCP socket — even if they're in the middle of some some CPU-intensive hot loop — and which makes sure to "push down" that failure into resource-handles like DB sockets, such that the DB "sees" the failure and gives up on its related long-running CPU-intensive task as well?

This is a Hard Problem in Java, with a huge number of little considerations involved: lots of calls to Thread.interrupted; async requests; CompletableFutures; moving any parallel streams to their own explicit ForkJoinPools, etc. You can see the Project Loom team slowly giving the Java stdlib a working-over in this style, but even after their work becoming Generally Available, library authors will still need to do all this stuff as well.

In Erlang/Elixir, meanwhile: 1. the accepted TCP connection is a process, 2. the web request runs either inside it or in another process linked to it, such that either one dying kills the other, 3. any concurrent Tasks get linked to the TCP connection process that spawned them as well; 4. any DB calls temporarily link the checked-out DB connection to the request process as well; and 5. adding request deadlines is as easy as calling a function to spawn a deadline timer pointed at the spawning process's own head.

Essentially, idiomatic Erlang/Elixir code gets this type of robustness for free, with zero additional lines of code. The moment you have an Erlang web server, you have a robust Erlang web server.

(Erlang/BEAM is also miles ahead of Golang in operationalizing concurrency, for separate reasons, mostly to do with goroutine resource leaks. Separate topic, but I just figured someone would ask.)

And then there's the fact that per-process heaps mean most short-running request-response type workloads can get away with never making a garbage-collection call, instead just allocating a pre-sized arena with each process, doing work, and then tossing away that arena when the process quits. So, as long as you've built your Erlang/Elixir app idiomatically, doing each task in a process that doesn't survive the lifetime of the task — then you'll never see the same sort of gradual "putting off GC for later" asymptotic allocated-memory climb that you see in a most GCed languages.

[+] hinkley|4 years ago|reply
It does sort of seem like the majority of people who understand this end up at the sort of company that is willing to try out a new tool.

I think in a lot of ways StackOverflow has changed this dynamic. Previously I benefited from memorizing all of the API functions that return slightly different responses than their peers. This one returns null instead of an empty array. This one mutates the second argument. This one has n^2 complexity, and so on.

Now, after doing Java, Javascript, Ruby, lots of bash, a bit of Python, and a few sundry other things, I don't trust my memory. I go check every time, because it's cheap enough to find the comments that say "be careful".

What I need most is a toolbox full of Important Questions. Important Questions scale logarithmically across languages and many problem domains. Important Answers do not.

[+] killingtime74|4 years ago|reply
Many of these things are not exclusive to elixir though. Scala and Akka come to mind
[+] codeptualize|4 years ago|reply
I find it strange how always the "mainstream" and "not popular enough " arguments comes up in any Elixir related post.

Does tech have to be "mainstream" to use it? I would say it doesn't.

Take Erlang, or OCaml, or F#, I wouldn't call those mainstream but they are great languages that solve real problems, and people using them seems generally very positive about them.

All you need is enough popularity and enough companies using and backing it for it to be maintained. I think Elixir has this.

Can't speak to the hiring situation but I wonder how problematic it can be given all the stories of how easy it is to onboard people and plenty of posts and comments of devs wanting to do Elixir. Even if, it depends on your situation, you don't always need a big workforce to do big things, see Whatsapp for example.

[+] arcturus17|4 years ago|reply
I run a growing agency and we run primarily on React + Django, but I really want to give Elixir a shot at some point.

I find its concurrency features, purported developer productivity, and it’s positioning as a “niche but popular” tech (these can be nice to acquire technical clients) very appealing.

Does anyone have any experience running an Elixir consultancy / agency / software house? Or freelancing? How is the market and your general experience?

[+] cultofmetatron|4 years ago|reply
I'm running an elixir startup

pros:

- web-socket story is the goat (and I used to write nodejs)

- ecto database library is amazing

- productivity is on par with django/rails

- performance is comparable to go. sub 100ms response times are normal

cons

- not many drop in libraries.

- hiring engineers is a pain but plenty are interested in learning

- libraries are not as used so you're more likely to run into a big in edge libraries.

- deployment is more complex if you want to use the mesh features

So far, I'm happy with it. There are certain features specific to my startup that would elixir/otp made easy to create. We're getting traction and elixir's strengths are a huge part of that.

[+] ipnon|4 years ago|reply
Anyone who knows Rails or Django can pick up Phoenix and anyone who likes Elixir is going to be the kind of person you want to hire.
[+] lawik|4 years ago|reply
Yeah, freelancing mostly. Lots of developers wanting to work with it, so finding engaged devs has been easy for me when I've wanted reinforcement.

Haven't had a gap in clients for a year and a half of straight Elixir work. Have more opportunities than I can feasibly execute on.

Finding the right companies and connections is a bit of luck and a bit of networking of course. But most of the companies I've worked with are not well known in the community. There's plenty of usage in the wild.

[+] news_to_me|4 years ago|reply
I've been working on Elixir projects freelance for over a year now, and it's become my preference for new projects. Elixir is one of my favorite languages because I feel like it really increases the leverage each developer has in a project.
[+] rubyn00bie|4 years ago|reply
I would probably recommend against this for most things if you're running an agency. Hiring experienced Elixir developers is not easy nor cheap; and for your clients, if they want to hire developers, at some point, are going to have a really difficult time.
[+] R0b0t1|4 years ago|reply
Erlang/Elixir were designed for telecommunication programs. If what you are doing is even vaguely like this Erlang/Elixir are going to be perhaps the best language you could pick. If you need to make a GUI or handle a CRUD app it may well be the worst language you could pick.

Elixir is a lot more forgiving, but with Erlang you can tell it was made for telecom switches.

[+] ozmaverick72|4 years ago|reply
All these stories can be distilled into - "I picked something I liked and we made it work. Yay team"
[+] rishav_sharan|4 years ago|reply
Lots of posts here are talking about Elixir's concurrency and performance, but in benchmarks like techempower, Elixir comes fairly low.

Can someone help me rationalize this discrepancy?

Also, in general, for a Digital Ocean droplet, how many requests per second (db query based) can Elixir handle while maintaining a sub 200ms latency?

[+] jtwebman|4 years ago|reply
Almost no business application is written for performance at raw request speed. What Elixir brings is far more the that. Watch this if you want to understand why so many people fall in love with it. https://youtu.be/JvBT4XBdoUE
[+] jrsj|4 years ago|reply
Well it’s pretty competitive if you limit it to dynamic languages + eliminate some outliers (weird non-Node JS runtimes, web frameworks mostly written in C that happen to be called from Python/PHP, etc)
[+] masijo|4 years ago|reply
I really wish there were more remote Elixir job offers. Seems like such a great productive language to use, and Phoenix with LiveView is just great.
[+] babelfish|4 years ago|reply
> The need for concurrency and fault-tolerance made Elixir an obvious choice for this application, but that alone wasn't enough to seal the deal.

What? Why does this make Elixir an obvious choice? Most (if not all) major languages offer concurrency primitives (e.g. goroutines), and fault-tolerance is included as a requirement by default for any sufficiently complex distributed system, but has little to do with the languages/frameworks used to build that system. Not seeing why these requirements make Elixir a better choice than any other language

[+] lostcolony|4 years ago|reply
That's not really true.

Or rather, the need for the distributed system to be fault tolerant is, but downplaying the language/framework isn't entirely.

Kubernetes has definitely made it so the distributed tooling of Erlang is less valuable; many of the things it provides you can also get with Kubernetes. The tradeoff being that Kubernetes is far more complex (but, also allows for things Erlang doesn't have).

But what Kubernetes can't do is help you write correct programs. That is, if an error happens, what do you do? In most languages, you catch the ones you can predict and handle them. For the others, you let them trickle up until someone catches them, or the app crashes. The problem is figuring out where to handle them, and to make sure you really -are- handling the things you know how to handle.

Erlang flips this. Handling things becomes far less important as isolating failure. If something goes wrong ~here~, where else is there state that is likely wrong, and how do we get it all back into a good state?

This is a really powerful approach, as it ends up being far more robust, for far less work. It's harder to get 'incorrect' behavior this way; rather than have to enumerate the unhappy paths, and how to address each, you just have to declare dependencies between processes and how, should they find themselves on an unhappy path, to drop their state and get a known good one.

[+] macintux|4 years ago|reply
> fault-tolerance is included as a requirement by default for any sufficiently complex distributed system, but has little to do with the languages/frameworks used to build that system

Erlang/Elixir have an extremely compelling story when it comes to fault-tolerance. You can only argue that all languages are created equal in this regard if you fall back to the "everything is Turing-complete so they're equivalent" argument.

Erlang and its VM were built from the ground up to work closely together with fault tolerance in mind, in a context where a few minutes of downtime meant severe financial penalties.

[+] pawelduda|4 years ago|reply
I think it's because Elixir runs in Erlang VM which was built from the ground-up to satisfy these requirements... And it's been around for a very long time with very good track record.
[+] mikeryan|4 years ago|reply
I can understand deciding Elixer is a good solution for for concurrency. What I couldn’t understand from the story was why it was needed. Unless the IDE had some sort of real-time shared coding?

There’s nothing in the list of requirements that couldn’t be done over http it all seems asynchronous? Scale here seems like it would be small.

Three months is almost zero time for a team of 4. I’m glad it all worked out but I have a harder time from the story understanding how using Elixer was the right choice vs a stack they were more familiar and confident on condieribg the constraints.

[+] krishvs|4 years ago|reply
Looking for some advice.

We have written several microservices primarily for websockets in Elixir. They are great with literal zero maintenance costs..but how do Elixir developers handle the following when going all in:

1. Long running workflows - there do not seem to be popular frameworks like camunda, jbpm, temporal or cadence for elixir

2. Integration libraries - similar to apache camel

3. Inbuilt scripting engines to run user scripts like nashorn, graaljs or groovy

We really enjoy working with rails and would like to go all in into elixir. But the ecosystem of available frameworks seems to always come in the way and makes us choose spring boot or rails.

[+] lostcolony|4 years ago|reply
Pre-emptive caveat: I do not know much about the three things you mention. THAT SAID, I'm familiar with Erlang, and moderately familiar with Elixir, so wanted to still give you some areas to explore.

For #3, you probably would need to NIF out to something. You can also execute an uncompiled script of Erlang using escript, but that, obviously, is not something you'd expect most users to learn (and not sure you can execute it in a running Erlang context, rather than from an external shell). You can also evaluate a string, and/or compile and load new Erlang code from a running Erlang program, but these are suuuuuper dangerous if it's user supplied.

For #1, I've never seen anything, but if you just need something that allows you to change out or customize logic on the fly you can do so in a pretty straightforward manner. Because it's a functional language, you can do stuff like have a stateful process template that you can swap out on the fly, i.e., submit a list of function identifiers a la [read_data/1, transform/1, write_data/1], and now whenever you call run(data), it spins up a new actor that effectively calls write(transform(read_data(data))). Technically you can even provide new code snippets (using one of the mechanisms from #1, or, if opening up an Erlang shell to the running instance, supplying it directly as a lambda), but you'll need to be mindful about persistence. I am not that well versed with workflow engines, but that partly comes from the fact that I haven't really seen the point given how easy many languages make it to create and customize workflows without having to learn special semantics.

I am not at all familiar with apache camel, but I think your concerns here aren't easily addressed; certainly, the library support for Erlang/Elixir isn't anywhere close to the JVM. But I -will- mention that sometimes writing the integration(s) you need to enable using a different technology are worth it.

[+] di4na|4 years ago|reply
For #3 in general the advice is a NIF or a Port to an engine (polar is a good example) or to use Luerl

For #2 i know nothing about this kind of stuff

For #1 it depends a lot. Something like Oban can be enough, or Ulf Wiger's Job or Broadway. These tends to be more ad hoc and extracted to independent services. It depends a lot of what kind of constraints you have for these workflows. There are lot of options but they are all more specific to use case and constraints than these broad projects that try to do it all.

[+] elcritch|4 years ago|reply
The other comments make good points, but here's a few more:

> 1. Long running workflows - there do not seem to be popular frameworks like camunda, jbpm, temporal or cadence for elixir

Oban seems good for job processing. Otherwise Elixir builds on Erlang's OTP. That means you can also use ets, mnesia, or even Rick's distributed dynamo application runners.

> 2. Integration libraries - similar to apache camel

Nothing quite like this, but you can make use of Flow or GenStage for data pipelines.

> 3. Inbuilt scripting engines to run user scripts like nashorn, graaljs or groovy

There's a nice Lua implementation 'Luerl' IIRC. Also as others mentioned you can do a NIF. In particular Rust & Rustler would provide lots of scripting language runtime.

[+] ciconia|4 years ago|reply
Off topic: Am I the only one who finds the stock photos in the article off-putting? They have nothing to do with the subject matter, except in a very indirect, sort-of-metaphorical way. I would take the article much more seriously if they weren't there.
[+] leephillips|4 years ago|reply
You’re not alone. Those gratuitous, unimaginative photographs (one mirror-flipped, suggesting obliviousness somewhere in the assembly line process), combined with the prolix, buzzword laden, soggy prose, emit a strong corporate odor that made me want to turn away. Pity, because the core of the content is somewhat interesting.
[+] LeonidasXIV|4 years ago|reply
One of them is mirrored and the way Canon is unreadable on the camera is vaguely annoying me.
[+] aswinmohanme|4 years ago|reply
The best things about Elixir is it's pattern matching and it's inbuilt documentation tool. Each and every document for every package is consistent, which are exploited by the IDE tools for stellar in editor help.
[+] leke|4 years ago|reply
> We had two viable choices for the new application that needed to be built---Rails and Phoenix. The team to which we were delivering the project had no Elixir experience at all, so a choice to build a Phoenix app represented a choice to adopt Elixir.

*Laravel and all the other PHP frameworks waving their hands frantically...

Hello, Hello!

[+] mouldysammich|4 years ago|reply
I wish there were more roles for elixir newbies/general newbies out there. I've been learning some elixir basics and it seems like itd be a tonne of fun to work with.
[+] jatins|4 years ago|reply
Folks who have used Elixir in a team environment (as opposed to for personal use), is the lack of types an issue in navigating big/unfamiliar codebases?
[+] xupybd|4 years ago|reply
Wow that is insane to do that much in 3 months.

I'm not sure how big the team was but I'm impressed.

[+] colesantiago|4 years ago|reply
Just curious, seems to see a lot of Elixir posts crop up on HN lately.

I know a startup that did £75K+ in sales in the first week with only just using node + heroku.

Could the same be applied to Elixir if it is really that good?

Are there any pitfalls that one should know about?

[+] bastawhiz|4 years ago|reply
Your tech stack is going to have 99.99% less to do with your first week's success than your business plan and execution.
[+] RobertKerans|4 years ago|reply
This seems slightly bizarre -- sorry for /s but if you have engineers who are familiar with {language} rather than Node then they'll probably generate more sales for your company building an application in {language} than they would building in in Node. The pitfalls would be that it'll be slower to get an application in {language} to production if the engineers know how program Node but not {language}.
[+] vendiddy|4 years ago|reply
Elixir on Heroku is just as viable (we're still running on a single heroku Dyno and postgres instance on Elixir).

Not having much info, my guess is many languages would worked out for that startup.