<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Amine Affif</title>
    <description>The latest articles on DEV Community by Amine Affif (@amineaffif).</description>
    <link>https://dev.to/amineaffif</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4162234%2Fcb499ed5-5a3a-48e3-b1f2-7394a22ef75b.jpg</url>
      <title>DEV Community: Amine Affif</title>
      <link>https://dev.to/amineaffif</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/amineaffif"/>
    <language>en</language>
    <item>
      <title>A 44-second export: measure before you look</title>
      <dc:creator>Amine Affif</dc:creator>
      <pubDate>Sun, 04 Oct 2026 18:26:20 +0000</pubDate>
      <link>https://dev.to/amineaffif/a-44-second-export-measure-before-you-look-4c19</link>
      <guid>https://dev.to/amineaffif/a-44-second-export-measure-before-you-look-4c19</guid>
      <description>&lt;p&gt;When I hit a slowdown, I write three things down first: what I instrument, what I compare, and what would make me drop my hypothesis. Ten minutes. Without it, I follow the first lead that looks logical, and that doesn't make it the right one.&lt;/p&gt;

&lt;p&gt;Three examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 44-second export
&lt;/h2&gt;

&lt;p&gt;An export took 44 seconds. I measured before assuming: more than 42 seconds were spent in the application, before the call to the service even started. The service itself answered in a little over a second.&lt;/p&gt;

&lt;p&gt;The culprit: cascading queries. A generic example, not the original code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 1 query for the accounts, then 1 per account&lt;/span&gt;
&lt;span class="n"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# 2 queries, whatever the number of accounts&lt;/span&gt;
&lt;span class="n"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:employees&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The biggest accounts
&lt;/h2&gt;

&lt;p&gt;Another slowdown, only on the very large accounts. I started over: I instrumented the front end and the back end, then compared three account sizes. What grows with the account is the bottleneck.&lt;/p&gt;

&lt;p&gt;I fixed the cascading queries instead of adding a cache, because a cache hides the problem without solving it. The backend fix is in production, and I went through the other places with the same flaw.&lt;/p&gt;

&lt;h2&gt;
  
  
  The display bug
&lt;/h2&gt;

&lt;p&gt;It looked like a UI bug. Digging back, it was a business rule being bypassed. What settled it: no screen in the app lets you create that state by hand, so it came from somewhere else. The subject was no longer the display, it was a decision for someone a level up.&lt;/p&gt;

&lt;p&gt;And if an analysis I posted turns out to be wrong, I correct it in the same place.&lt;/p&gt;

&lt;p&gt;The rest of how I work is at &lt;a href="https://amineaffif.com/en/methode" rel="noopener noreferrer"&gt;amineaffif.com/en/methode&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Amine Affif, full-stack developer in Paris.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Version française : &lt;a href="https://dev.to/amineaffif/un-export-de-44-secondes-mesurer-avant-de-chercher-37ip"&gt;Un export de 44 secondes : mesurer avant de chercher&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>debugging</category>
      <category>performance</category>
      <category>rails</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Un export de 44 secondes : mesurer avant de chercher</title>
      <dc:creator>Amine Affif</dc:creator>
      <pubDate>Sun, 04 Oct 2026 18:24:47 +0000</pubDate>
      <link>https://dev.to/amineaffif/un-export-de-44-secondes-mesurer-avant-de-chercher-37ip</link>
      <guid>https://dev.to/amineaffif/un-export-de-44-secondes-mesurer-avant-de-chercher-37ip</guid>
      <description>&lt;p&gt;Quand je tombe sur une lenteur, j'écris d'abord trois choses : ce que j'instrumente, ce que je compare, et ce qui me ferait abandonner mon hypothèse. Dix minutes. Sans ça, je pars sur la première piste qui a l'air logique, et ça ne veut pas dire que c'est la bonne.&lt;/p&gt;

&lt;p&gt;Trois exemples.&lt;/p&gt;

&lt;h2&gt;
  
  
  L'export de 44 secondes
&lt;/h2&gt;

&lt;p&gt;Un export mettait 44 secondes. J'ai mesuré avant de supposer : plus de 42 secondes se passaient côté application, avant même l'appel au service. Le service, lui, répondait en un peu plus d'une seconde.&lt;/p&gt;

&lt;p&gt;Le coupable : des requêtes en cascade. Un exemple générique, ce n'est pas le code d'origine :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 1 requête pour les comptes, puis 1 par compte&lt;/span&gt;
&lt;span class="n"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# 2 requêtes, quel que soit le nombre de comptes&lt;/span&gt;
&lt;span class="n"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:employees&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Les plus gros comptes
&lt;/h2&gt;

&lt;p&gt;Une autre lenteur, uniquement sur les très gros comptes. Je suis reparti de zéro : j'ai instrumenté le front et le back, puis comparé trois tailles de compte. Ce qui grossit avec le compte, c'est le goulot.&lt;/p&gt;

&lt;p&gt;J'ai corrigé les requêtes en cascade plutôt que d'ajouter du cache, parce qu'un cache masque le problème sans le régler. Le correctif backend est en production, et j'ai recensé les autres endroits qui avaient le même défaut.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le bug d'affichage
&lt;/h2&gt;

&lt;p&gt;Ça ressemblait à un bug d'interface. En remontant, c'était un contournement d'une règle métier. Ce qui a tranché : aucune vue de l'application ne permet de créer cet état à la main, donc il venait d'ailleurs. Le sujet n'était plus l'affichage, c'était une décision à prendre un niveau au-dessus.&lt;/p&gt;

&lt;p&gt;Et si une analyse que j'ai postée se révèle fausse, je la corrige au même endroit.&lt;/p&gt;

&lt;p&gt;Le reste de ma façon de travailler est sur &lt;a href="https://amineaffif.com/methode" rel="noopener noreferrer"&gt;amineaffif.com/methode&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Amine Affif, développeur full-stack à Paris.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;English version: &lt;a href="https://dev.to/amineaffif/a-44-second-export-measure-before-you-look-4c19"&gt;A 44-second export: measure before you look&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>debugging</category>
      <category>performance</category>
      <category>rails</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
