
Learnings from One Year of Building an Open Source Elixir Application - achariam
http://achariam.com/elyxel/
======
agentgt
_> Elyxel was designed and built with performance in mind. Styles and any
additional flourishes were kept to a minimum. My choice of Elixir & Phoenix
was driven by this consideration as well. Most of the pages are well under 100
kilobytes and load in less than 100 milliseconds5. I find it's always helpful
to keep performance in the back of your mind when building something._

Thats much appreciated but I was kind of hoping you (the author) would go into
more details about request time. Most people can (and should) do the above.
However I would be more interested in what Elixer + CRUD is like particularly
for _TTFB_. Like does the author do streaming (I don't necessarily mean
websockets or comet)?

After all if the TTFB is really slow the CSS optimizations and what not matter
little.

In traditional request per thread (or whatever is analagous) web framework
paradigms the request is a single thread and often waits for the database to
finish before moving on to display the page. I would imagine Elixir has a
better answer at least for read only pages.

~~~
pdimitar
On my virtual Debian, the _development_ version of a relatively complex
website -- which is probably anywhere between 5 to 30 times slower than
production -- has 450ms for the _first ever request after the server starts_.
Anything from then on goes between 0.2 to 12ms.

Not really telling you much, I know, but these are pretty standard numbers for
Elixir + Phoenix apps.

------
brosky117
I really enjoyed this article and the one about the ambient notification cube!
Well-written. It's nice to hear someone else talk about how hard it it to stay
consistent with worthwhile projects while maintaining a day job. Congrats on
sticking it out!

~~~
achariam
Thank you for the kind words, really appreciate it :)

------
deedubaya
One of the interesting things about the Elixir/Phoenix community is that
building your own authentication system seems to be encouraged. Even if you're
using one of the plugs available (guardian?) you still have to do a ton of
manual lifting.

~~~
rpazyaquian
This seems to be the case in many places outside of Rails. I know that
Clojure, at least, seems to encourage implementing things yourself by way of
leveraging smaller libraries and modules.

Auth is genuinely hard, and turnkey solutions often aren't enough.

~~~
fny
Auth is genuinely hard, and a hand-rolled solution's _definitely_ not
enough...

Given the massive attack surface for a web application, it's absurd to think
someone could (or __should __*) develop an entire auth framework from scratch
for all their projects. Turnkey solutions, like Ruby 's Devise, are a godsend.
Even in situations were a custom flow was needed, it's saved both me and my
clients hundreds of hours.

In addition, I benefit from the community around a turnkey solution. Think of
all the years the software has been tested by in umpteen production
environments. Think of all the people that have an eye on the code and report
security flaws while you sleep. Your custom session management implementation
will never have that benefit.

Also, why the hell are you building auth when you could be building app? Is
that really such a critical experiential part of your app that you can't
possibly rely on something turnkey and then move on to the features that
actually matter?

~~~
pdimitar
All of what you say is true but I feel important details are lost.

Elixir's Phoenix framework has very good plugins -- like Guardian -- that give
you 95% of the tools you might need for your own security solution and you can
assemble it together in 15-60 minutes (this of course assumes your security
model isn't wildly different than what the various plugins support). You have
separate Plugs -- think of them as pipes of sort -- who handle cookie session
management, another that handles JWT tokens, HTTP basic auth etc.

The only thing you must do is to assemble such pieces in a code module that
basically serves as a pipeline with several Plugs (pipes) connected in the
order you deem appropriate for the security model of your app. Any of these
Plugs can modify or remove headers or tokens, can consult a 3rd party system
(say, for single sign-on), can provide throttling, temporarily lock out an
account that made too many invalid login attempts, can refuse a session due to
non-whitelisted IP, etc. etc.

So no, you're not inventing cookie session management or anything there. You
simply have control on which security mechanisms -- and when, and at which
conditions -- happen on request.

------
ploggingdev
Interesting post, more so because I am working on a project that has many
characteristics of a link aggregator.

While implementing the ranking algorithm, which is very similar to the one
mentioned in the article, I decided to run a periodic job every 60 seconds
that updates the rank for each submission and stores it in the database so
querying the ranked data is more efficient than recalculating the rank on
every page request. Are you doing something similar or did you take a
different approach?

Ranking all stories works well if the total number of submissions is a small
number, but I imagine the approach is a little different for large sites like
HN. Ranking all submissions periodically seems like a waste since people
rarely view submissions beyond 10 pages. One approach is just to rank
submissions from the past _n_ days, where n depends on the average daily
submission volume.

For the part that displays time since a submission was made, I implemented the
HN model, where it displays only minutes, hours and days. Python code here :
[https://dpaste.de/5d1w](https://dpaste.de/5d1w)

> Elyxel was designed and built with performance in mind. Styles and any
> additional flourishes were kept to a minimum. My choice of Elixir & Phoenix
> was driven by this consideration as well. Most of the pages are well under
> 100 kilobytes and load in less than 100 milliseconds5. I find it's always
> helpful to keep performance in the back of your mind when building
> something.

Once you start to scale, the bottleneck is rarely the application layer. For
the typical crud web app it's likely to be the database.

~~~
tim333
Not sure if it's relevant but you can avoid having elapsed time in the formula
and instead inflate the scores of the newer stories
([https://news.ycombinator.com/item?id=9889750](https://news.ycombinator.com/item?id=9889750))

Then you only have to recalculate when there is a submission or vote.

------
codegeek
Great writing. Elixir/Phoenix has been on my radar for learning something
exciting considering it is faster out of the box and can handle tons of
concurrent connections.

For the lazy, here is the github link from this article:

[https://github.com/achariam/elyxel](https://github.com/achariam/elyxel)

------
darkmarmot
Having a sign up button or perhaps context or text on the site might've been
helpful...

~~~
achariam
You're completely right, it seems a little counterintuitive but one thing I
learned early on while building a different community site (Designer News) was
the way to build a wholesome community was to be invite only in the beginning.
That and real first and last names.

Which means it's a poor user experience. Sorry for the trouble, I wonder if
any folks have better ideas here?

~~~
bpicolo
Not a single page even mentions that it's invite only =/. Context for that
would be a good start heh

------
overcast
It would be awesome if elyxel.com wasn't so esoteric.

