<?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: Jonathan Duberville</title>
    <description>The latest articles on DEV Community by Jonathan Duberville (@jducraft).</description>
    <link>https://dev.to/jducraft</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F783256%2F252f67aa-e2fc-47c0-a2a5-4fa28cc1fdfb.jpeg</url>
      <title>DEV Community: Jonathan Duberville</title>
      <link>https://dev.to/jducraft</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jducraft"/>
    <language>en</language>
    <item>
      <title>3 Days to Save the Release: From 3.15s to 233ms</title>
      <dc:creator>Jonathan Duberville</dc:creator>
      <pubDate>Thu, 11 Dec 2025 10:48:16 +0000</pubDate>
      <link>https://dev.to/jducraft/3-days-to-save-the-release-from-315s-to-233ms-ni3</link>
      <guid>https://dev.to/jducraft/3-days-to-save-the-release-from-315s-to-233ms-ni3</guid>
      <description>&lt;p&gt;&lt;em&gt;Lessons from a successful optimization mission — by a non-expert&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Some Context
&lt;/h2&gt;

&lt;p&gt;The API is central to a migration program. Problem: critical latencies are blocking its release to production.&lt;/p&gt;

&lt;p&gt;The symptoms: MongoDB CPU at 150%, connections jumping from 400 to 1500, high error rate, requests exceeding 30 seconds.&lt;/p&gt;

&lt;p&gt;Here's the approach I followed and what I learned from it.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Tackle This Kind of Problem?
&lt;/h2&gt;

&lt;p&gt;Before diving in, I gathered as much information as possible: existing audits, interviews, monitoring dashboards, bug history. I complemented this with a code review to assess complexity, spot anti-patterns and identify quick wins.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🤖 &lt;strong&gt;AI Accelerator&lt;/strong&gt;: The agent scanned the codebase, identified anti-patterns and documented the structure. It helped me build a macro view of the system.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Famkx3o4adn5087vq8rti.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Famkx3o4adn5087vq8rti.png" alt="Cynefin Framework" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using the &lt;a href="https://en.wikipedia.org/wiki/Cynefin_framework" rel="noopener noreferrer"&gt;Cynefin framework&lt;/a&gt;, I identified that we were in the &lt;strong&gt;Complex&lt;/strong&gt; domain: multiple interconnected factors, impossible to predict the impact of an optimization without trying it.&lt;/p&gt;

&lt;p&gt;Hence the approach: &lt;strong&gt;Probe → Sense → Respond&lt;/strong&gt; — experiment, observe, adjust.&lt;/p&gt;




&lt;h2&gt;
  
  
  An Iterative Strategy: Probe → Sense → Respond
&lt;/h2&gt;

&lt;p&gt;No tooling, no data. No data, no strategy. I used a load testing tool and several monitoring solutions to collect as much information as possible.&lt;/p&gt;




&lt;h3&gt;
  
  
  Smoke Test
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Probe&lt;/strong&gt;: Each test uses a simple and identical profile: gradual ramp-up to 500 virtual users, 15-minute plateau, then ramp-down.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F070bhnhqhrd3drf5c93o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F070bhnhqhrd3drf5c93o.png" alt="User Profile" width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sense&lt;/strong&gt;: Too many 504 errors, unstable MongoDB — unusable results. Root causes: the scenario reused the same identifiers (write conflicts) and the code contained queries without indexes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9cotizru5a3t35q6yu90.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9cotizru5a3t35q6yu90.png" alt="Cycle 1" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: Unusable (too many errors to measure)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Respond&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Created indexes on critical fields&lt;/li&gt;
&lt;li&gt;Improved test scenario (randomization, realistic distribution)&lt;/li&gt;
&lt;li&gt;Created a dedicated test environment&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;🤖 &lt;strong&gt;AI Accelerator&lt;/strong&gt;: The agent identified the fields to index and generated the test scripts.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Establishing a Baseline
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Probe&lt;/strong&gt;: Load test with the corrected scenario on the dedicated environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sense&lt;/strong&gt;: First usable results. High latency, but reliable measurements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbilo66qby2j722u1b635.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbilo66qby2j722u1b635.png" alt="Baseline" width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Result (baseline)&lt;/strong&gt;: 101 req/s, 2.56% errors, P99 9.9s, average 3.15s&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Respond&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adjusted Kubernetes autoscaling (HPA)&lt;/li&gt;
&lt;li&gt;Increased replica count&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Testing Horizontal Scaling ⚠️
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Probe&lt;/strong&gt;: New load test.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sense&lt;/strong&gt;: Pods saturate before autoscaling kicks in.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91urpkbe947chk7fhxhc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91urpkbe947chk7fhxhc.png" alt="Cycle 3" width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: 82 req/s, 4.17% errors, P99 12.3s, average 4.09s ⚠️&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Regression!&lt;/strong&gt; More replicas = more concurrent MongoDB connections = more contention. We're just moving the problem around.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Respond&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Increased CPU and RAM resources per pod&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Testing Vertical Scaling
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Probe&lt;/strong&gt;: New load test.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sense&lt;/strong&gt;: Observability reveals Out Of Memory errors and frequent restarts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd22x872bdknquyy19ccs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd22x872bdknquyy19ccs.png" alt="Cycle 4" width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: 162 req/s, 0.68% errors, P99 5.86s, average 1.58s&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;✅ Throughput +60%, errors -73%. But latency remains high — the problem is now in the code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Respond&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Optimized MongoDB queries (removed expensive aggregations)&lt;/li&gt;
&lt;li&gt;Refactored critical algorithms&lt;/li&gt;
&lt;li&gt;Optimized write parameters&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;🤖 &lt;strong&gt;AI Accelerator&lt;/strong&gt;: The agent generated regression tests and assisted with code refactoring.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Testing Application Optimizations
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Probe&lt;/strong&gt;: New load test.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sense&lt;/strong&gt;: The optimizations are paying off.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptm6wvqnf3ad08m5ebns.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptm6wvqnf3ad08m5ebns.png" alt="Cycle 5" width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final result ✅&lt;/strong&gt;: 200 req/s, ~0% errors, P99 0.67s, average 233ms&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;✅ Throughput doubled compared to baseline, P99 dropped from 9.9s to 0.67s.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Exit — Knowing When to Stop
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F097nv0ciobu6azkl667v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F097nv0ciobu6azkl667v.png" alt="Final Result" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;200 req/s, P99 under one second, near-zero errors: release constraints are met.&lt;/p&gt;

&lt;p&gt;In Cynefin terms, this is the transition from the &lt;strong&gt;Complex&lt;/strong&gt; domain to the &lt;strong&gt;Complicated&lt;/strong&gt; domain: we've learned enough, future optimizations become predictable. Without production data, going further would be premature optimization.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This mission shows that a &lt;strong&gt;Probe → Sense → Respond&lt;/strong&gt; approach delivers fast gains on a complex system. AI agents didn't replace expertise — it's still humans who observe and decide — but they accelerated each cycle. The faster you iterate, the faster you learn.&lt;/p&gt;




&lt;h3&gt;
  
  
  Key Takeaways
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Measure before and after each change.&lt;/strong&gt; Intuition isn't enough, and an optimization can make things worse.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Get your test scenario right.&lt;/strong&gt; An unrealistic scenario produces misleading results.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Navigate across layers.&lt;/strong&gt; Infra, code, and database form a system. Being able to read Kubernetes metrics, profile MongoDB, and refactor code in the same day is a decisive advantage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Get the right tools.&lt;/strong&gt; Without load testing, observability, and profiling tools, optimization is blind.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use AI agents to accelerate.&lt;/strong&gt; They don't replace expertise, but they amplify execution velocity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Define an exit criterion.&lt;/strong&gt; SLOs define when it's "good enough". Without them, you risk over-optimizing.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Bonus&lt;/strong&gt;: a mature Platform Engineering setup remains a prerequisite for these gains to materialize.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>learning</category>
      <category>performance</category>
      <category>mongodb</category>
      <category>api</category>
    </item>
    <item>
      <title>On a 3 jours pour sauver la MEP: de 3.15s à 233ms</title>
      <dc:creator>Jonathan Duberville</dc:creator>
      <pubDate>Thu, 11 Dec 2025 09:51:44 +0000</pubDate>
      <link>https://dev.to/jducraft/on-a-3-jours-pour-sauver-la-mep-de-315s-a-233ms-4fl4</link>
      <guid>https://dev.to/jducraft/on-a-3-jours-pour-sauver-la-mep-de-315s-a-233ms-4fl4</guid>
      <description>&lt;p&gt;&lt;em&gt;Mes conseils de non-expert issus d'une mission d'optimisation réussie&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmg598ybmj4s6bxjksrxg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmg598ybmj4s6bxjksrxg.png" alt=" " width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Un peu de contexte
&lt;/h2&gt;

&lt;p&gt;L'API est centrale pour un programme de migration. Problème : des latences critiques bloquent sa mise en production.&lt;/p&gt;

&lt;p&gt;Les symptômes : CPU MongoDB à 150%, connexions qui passent de 400 à 1500, taux d'erreurs élevé, requêtes dépassant 30 secondes.&lt;/p&gt;

&lt;p&gt;Voici la démarche que j'ai suivie et ce que j'en retiens.&lt;/p&gt;




&lt;h2&gt;
  
  
  Comment attaquer ce genre de sujet ?
&lt;/h2&gt;

&lt;p&gt;Avant de foncer, j'ai rassemblé un maximum d'informations : audits existants, interviews, dashboards de monitoring, historique de bugs. J'ai complété par une revue de code pour évaluer la complexité, repérer les anti-patterns et identifier des quick wins.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🤖 &lt;strong&gt;Accélérateur IA&lt;/strong&gt; : L'agent a scanné le codebase, identifié les anti-patterns et documenté la structure. Il m'a aidé à construire une vision macro du système.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Famkx3o4adn5087vq8rti.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Famkx3o4adn5087vq8rti.png" alt="Cynefin Framework" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En m'appuyant sur le framework &lt;a href="https://fr.wikipedia.org/wiki/Cadre_conceptuel_Cynefin" rel="noopener noreferrer"&gt;Cynefin&lt;/a&gt;, j'ai identifié qu'on était dans le cadrant &lt;strong&gt;Complexe&lt;/strong&gt; : plusieurs facteurs interconnectés, impossible de prédire l'impact d'une optimisation sans l'essayer.&lt;/p&gt;

&lt;p&gt;D'où l'approche : &lt;strong&gt;Probe → Sense → Respond&lt;/strong&gt; — expérimenter, observer, ajuster.&lt;/p&gt;




&lt;h2&gt;
  
  
  Une stratégie itérative : Probe → Sense → Respond
&lt;/h2&gt;

&lt;p&gt;Sans outillage, pas de données. Sans données, pas de stratégie. J'ai utilisé un outil de test de charge et plusieurs solutions de monitoring pour collecter un maximum d'informations.&lt;/p&gt;




&lt;h3&gt;
  
  
  Smoke Test
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Probe&lt;/strong&gt; : Chaque tir utilise un profil simple et identique : montée progressive jusqu'à 500 utilisateurs virtuels, plateau de 15 minutes, puis descente.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F070bhnhqhrd3drf5c93o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F070bhnhqhrd3drf5c93o.png" alt="User Profile" width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sense&lt;/strong&gt; : Trop d'erreurs 504, MongoDB instable — résultats inexploitables. En cause : le scénario réutilisait les mêmes identifiants (write conflicts) et le code contenait des requêtes sans index.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9cotizru5a3t35q6yu90.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9cotizru5a3t35q6yu90.png" alt="Cycle 1" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Résultat&lt;/strong&gt; : Non exploitable (trop d'erreurs pour mesurer)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Respond&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Création d'index sur les champs critiques&lt;/li&gt;
&lt;li&gt;Amélioration du scénario de test (randomisation, distribution réaliste)&lt;/li&gt;
&lt;li&gt;Création d'un environnement dédié aux tests&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;🤖 &lt;strong&gt;Accélérateur IA&lt;/strong&gt; : L'agent a identifié les champs à indexer et généré les scripts de test.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Définir une référence
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Probe&lt;/strong&gt; : Tir de charge avec le scénario corrigé sur l'environnement dédié.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sense&lt;/strong&gt; : Premiers résultats exploitables. Latence élevée, mais mesures fiables.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbilo66qby2j722u1b635.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbilo66qby2j722u1b635.png" alt="Baseline" width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Résultat (baseline)&lt;/strong&gt; : 101 req/s, 2.56% erreurs, P99 9.9s, moyenne 3.15s&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Respond&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ajustement de l'autoscaling Kubernetes (HPA)&lt;/li&gt;
&lt;li&gt;Augmentation du nombre de replicas&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Tester le scaling horizontal ⚠️
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Probe&lt;/strong&gt; : Nouveau tir de charge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sense&lt;/strong&gt; : Les pods saturent avant que l'autoscaling réagisse.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91urpkbe947chk7fhxhc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91urpkbe947chk7fhxhc.png" alt="Cycle 3" width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Résultat&lt;/strong&gt; : 82 req/s, 4.17% erreurs, P99 12.3s, moyenne 4.09s ⚠️&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Régression !&lt;/strong&gt; Plus de replicas = plus de connexions MongoDB concurrentes = plus de contentions. On déplace juste le problème.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Respond&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Augmentation des ressources CPU et RAM par pod&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Tester le scaling vertical
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Probe&lt;/strong&gt; : Nouveau tir de charge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sense&lt;/strong&gt; : L'observabilité révèle des erreurs Out Of Memory et des restarts fréquents.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd22x872bdknquyy19ccs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd22x872bdknquyy19ccs.png" alt="Cycle 4" width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Résultat&lt;/strong&gt; : 162 req/s, 0.68% erreurs, P99 5.86s, moyenne 1.58s&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;✅ Débit +60%, erreurs -73%. Mais la latence reste élevée — le problème est maintenant côté code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Respond&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Optimisation des requêtes MongoDB (suppression des agrégations coûteuses)&lt;/li&gt;
&lt;li&gt;Refactoring des algorithmes critiques&lt;/li&gt;
&lt;li&gt;Optimisation des paramètres d'écriture&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;🤖 &lt;strong&gt;Accélérateur IA&lt;/strong&gt; : L'agent a généré des tests de non-régression et assisté le refactoring du code.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Tester les optimisations applicatives
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Probe&lt;/strong&gt; : Nouveau tir de charge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sense&lt;/strong&gt; : Les optimisations portent leurs fruits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptm6wvqnf3ad08m5ebns.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptm6wvqnf3ad08m5ebns.png" alt="Cycle 5" width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Résultat final ✅&lt;/strong&gt; : 200 req/s, ~0% erreurs, P99 0.67s, moyenne 233ms&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;✅ Débit doublé par rapport à la baseline, P99 passé de 9.9s à 0.67s.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Exit — Savoir quand s'arrêter
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F097nv0ciobu6azkl667v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F097nv0ciobu6azkl667v.png" alt="Résultat final" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;200 req/s, P99 sous la seconde, erreurs quasi-nulles : les contraintes de la MEP sont respectées.&lt;/p&gt;

&lt;p&gt;Dans Cynefin, c'est le passage du cadrant &lt;strong&gt;Complexe&lt;/strong&gt; au cadrant &lt;strong&gt;Compliqué&lt;/strong&gt; : on a suffisamment appris, les prochaines optimisations deviennent prévisibles. Sans données de production, aller plus loin serait de l'optimisation prématurée.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Cette mission montre qu'une approche &lt;strong&gt;Probe → Sense → Respond&lt;/strong&gt; permet des gains rapides sur un système complexe. Les agents IA n'ont pas remplacé l'expertise — c'est l'humain qui observe et décide — mais ils ont accéléré chaque cycle. Plus on itère vite, plus on apprend vite.&lt;/p&gt;




&lt;h3&gt;
  
  
  Ce que je retiens
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mesurer avant et après chaque changement.&lt;/strong&gt; L'intuition ne suffit pas, et une optimisation peut faire pire.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Soigner le scénario de test.&lt;/strong&gt; Un scénario non représentatif donne des résultats trompeurs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Naviguer entre les couches.&lt;/strong&gt; Infra, code, base de données forment un système. Savoir lire des métriques Kubernetes, profiler MongoDB et refactorer du code dans la même journée est un atout décisif.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;S'outiller correctement.&lt;/strong&gt; Sans outils de test de charge, d'observabilité et de profiling, l'optimisation est aveugle.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Utiliser des agents IA pour accélérer.&lt;/strong&gt; Ils ne remplacent pas l'expertise, mais ils amplifient la vélocité d'exécution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Définir un critère d'arrêt.&lt;/strong&gt; Les SLOs définissent quand c'est "assez bien". Sans eux, on risque de sur-optimiser.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Bonus&lt;/strong&gt; : une Platform Engineering mature reste un prérequis pour que ces gains se concrétisent.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>mongodb</category>
      <category>performance</category>
      <category>architecture</category>
      <category>ai</category>
    </item>
    <item>
      <title>Mutation Testing in NodeJS</title>
      <dc:creator>Jonathan Duberville</dc:creator>
      <pubDate>Sat, 01 Jan 2022 12:05:02 +0000</pubDate>
      <link>https://dev.to/jducraft/mutation-testing-in-nodejs-51ko</link>
      <guid>https://dev.to/jducraft/mutation-testing-in-nodejs-51ko</guid>
      <description>&lt;h2&gt;
  
  
  What is mutation testing?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;If you are reading this, we assume you are using TDD or that your coverage is nearly of 100%. If you are not complying to this requirement, start by building a strong Unit/Integration Test harness. Without a good coverage you won't get a lot of value out of this practice.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mutation testing is a way to check if your current tests (unit, integration, etc...) are precise enougth to catch random changes in your code base. The tool navigates through the code and creates mutants by modifying mostly conditions and values (such as constants or conditionals).&lt;/p&gt;

&lt;p&gt;For instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;will generate several mutants:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For each mutated version of your code, the tests base will be run.&lt;/p&gt;

&lt;p&gt;If the test is still &lt;code&gt;green&lt;/code&gt; the mutant will tagged this mutant state as &lt;code&gt;Survived&lt;/code&gt;, otherwise it will be tagged as &lt;code&gt;Killed&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The objective is to have as much &lt;code&gt;Killed&lt;/code&gt; mutants as possible, meaning the tests is covering most cases and that a change in the code will be catched by a unit test.&lt;/p&gt;

&lt;p&gt;We will be using Stryker as an automation tool:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://stryker-mutator.io/"&gt;https://stryker-mutator.io/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now! Let's go kill some mutants!&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Stryker dependencies
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-g&lt;/span&gt; stryker-cli
npm i &lt;span class="nt"&gt;-D&lt;/span&gt; stryker-html-reporter stryker-jest-runner stryker-typescript @stryker-mutator/core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;stryker init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change the &lt;code&gt;stryker.conf.js&lt;/code&gt; file to avoid analysing &lt;code&gt;.spec.ts&lt;/code&gt; files and add the plugins manually to avoid dependencies errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;mutator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;typescript&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;packageManager&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;npm&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;reporters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;progress&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;testRunner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;jest&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;transpilers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
    &lt;span class="na"&gt;coverageAnalysis&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;off&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;tsconfigFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tsconfig.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;mutate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src/**/*.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;!src/**/*.spec.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;htmlReporter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;baseDir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mutation&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stryker-html-reporter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stryker-jest-runner&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stryker-typescript&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Start the test (put your computer in a freezer!)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;stryker run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As always if you need help ask a friend 😊&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>testing</category>
      <category>programming</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
