Ciao!
If this week you have been dealing with performance issues, I feel you. Bonus points if it’s a legacy codebase like the one I’m dealing with.
I promised in this week’s post (link below) to update you on whether I crashed and burned, or managed to do something positive.
As described in the article, I opened the browser, submitted some forms, copied the cURLs, and translated them into Ruby. In other words, I wrote a script that simulates a user who submits many things really fast.
I fired up the terminal and, with my eyes glued to the metrics’ dashboard, I executed the script and stared at the screen for several minutes. At the end of the run, I confirmed the server managed the load without leaking memory.
With the stuffed database, the landing page for the authenticated user loaded fine. It’s when I moved to a screen that presents a list of orders that problems surfaced. After a couple of minutes and a JavaScript error, only a spinner was left hanging as a tombstone.
The RAM graph showed a nice vertical line on the backend, and the “Memory quota vastly exceeded” alert. Wow, we managed to do better than the usual “Memory quota exceeded” error. Hurrah!
Bad news; great news.
The script populates the database with data that mimics a real user. Under those circumstances, the application is not only slow, but it’s also broken. Not good.
However, now we can confidently fix the problem. We can assume (and verify) all the pages displaying long lists of things are slow and leaking memory. I’m not surprised given the lack of pagination, underperforming JSON serializers, and n+1 database queries.
We have multiple solutions we can combine: besides fixing what was mentioned above, we can benchmark anything and feel how fast is fast enough on each screen depending on the use-case, directly on staging.
Most importantly, we don’t need to solve all the issues. We can verify both in numbers and through the browser the impact of each intervention and shoot for good enough.
How to Investigate Performance Issues in a Web App with a Simple Script — If only I could simulate a user but faster. Wait a second! A person clicking things in a browser just sends HTTP requests to the server.
Elm Radio: Parse, Don’t Validate
The folks at Elm Radio cover an article I recently shared with you, Parse, Don’t Validate. Among other things, they discuss: Shotgun Parsing (i.e., mixing processing and validating data), wrap early / unwrap late, strengthening input vs. weakening output. Recommended regardless of your language of choice!
Conal Elliott - Denotational Design: From Meanings To Programs — I’ll share a methodology that I have applied many times over the last 20+ years when designing high-level libraries for functional programming. Functional libraries are usually organized around small collections of domain-specific data types together with operations for forming and combining values of those types. When done well, the result has the elegance and precision of algebra on numbers while capturing much larger and more interesting ideas. (I think I’ll watch it a few more times.)
How You Know — I’ve read Villehardouin’s chronicle of the Fourth Crusade at least two times, maybe three. And yet if I had to write down everything I remember from it, I doubt it would amount to much more than a page. Multiply this times several hundred, and I get an uneasy feeling when I look at my bookshelves. What use is it to read all these books if I remember so little from them? (This made me feel better about myself.)
Wow, this week has been heavy on me with legacy code, but I’ve killed it! What about you? What’s the one thing that made you proud this week?
Thanks for spending some time reading with me. Talk to you soon.
Yours truly,
Riccardo.