<?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: Fabrice Grenouillet</title>
    <description>The latest articles on DEV Community by Fabrice Grenouillet (@fabrice_grenouillet_c10f1).</description>
    <link>https://dev.to/fabrice_grenouillet_c10f1</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%2F3727768%2F41e8ee9a-ac1c-4e82-961d-9174197cc678.png</url>
      <title>DEV Community: Fabrice Grenouillet</title>
      <link>https://dev.to/fabrice_grenouillet_c10f1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fabrice_grenouillet_c10f1"/>
    <language>en</language>
    <item>
      <title>I stopped managing translations manually (and built this instead)</title>
      <dc:creator>Fabrice Grenouillet</dc:creator>
      <pubDate>Sat, 04 Apr 2026 06:24:30 +0000</pubDate>
      <link>https://dev.to/fabrice_grenouillet_c10f1/i-stopped-managing-translations-manually-and-built-this-instead-1m37</link>
      <guid>https://dev.to/fabrice_grenouillet_c10f1/i-stopped-managing-translations-manually-and-built-this-instead-1m37</guid>
      <description>&lt;p&gt;Managing multilingual content has always felt… wrong to me.&lt;/p&gt;

&lt;p&gt;In most projects, it quickly turns into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;duplicated fields (&lt;code&gt;title_en&lt;/code&gt;, &lt;code&gt;title_fr&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;messy i18n JSON files&lt;/li&gt;
&lt;li&gt;constant synchronization issues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At some point, I started wondering:&lt;br&gt;
why is this even a developer problem?&lt;/p&gt;

&lt;h2&gt;
  
  
  Rethinking the approach
&lt;/h2&gt;

&lt;p&gt;Instead of treating translations as something external (keys, files, etc.), I tried a different approach:&lt;/p&gt;

&lt;p&gt;What if multilingual support was part of the data model itself?&lt;/p&gt;

&lt;p&gt;So I built a small Airtable-like system where fields are multilingual by design.&lt;/p&gt;

&lt;p&gt;You write content once, and it becomes available in multiple languages automatically.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
Title: "Hello world"&lt;br&gt;
→ fr: Bonjour le monde&lt;br&gt;
→ es: Hola mundo&lt;/p&gt;

&lt;p&gt;No keys. No duplication. No sync issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Each field stores multiple language versions internally.&lt;/p&gt;

&lt;p&gt;On top of that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;automatic translation (using GPT)&lt;/li&gt;
&lt;li&gt;ability to override manually per language&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where it can be used
&lt;/h2&gt;

&lt;p&gt;The system can be accessed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;via API&lt;/li&gt;
&lt;li&gt;or directly inside a templating engine I’m building (Ekit Studio)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So content flows directly into rendering without extra i18n layers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this feels better
&lt;/h2&gt;

&lt;p&gt;This approach shifts the problem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;from code → to data&lt;/li&gt;
&lt;li&gt;from developers → to content structure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And in practice, it removes a lot of friction.&lt;/p&gt;

&lt;p&gt;Curious to hear from others&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>i18n</category>
      <category>node</category>
    </item>
    <item>
      <title>I’m building a project-based content &amp; templating tool — looking for beta testers</title>
      <dc:creator>Fabrice Grenouillet</dc:creator>
      <pubDate>Wed, 04 Feb 2026 08:30:39 +0000</pubDate>
      <link>https://dev.to/fabrice_grenouillet_c10f1/im-building-a-project-based-content-templating-tool-looking-for-beta-testers-1cm</link>
      <guid>https://dev.to/fabrice_grenouillet_c10f1/im-building-a-project-based-content-templating-tool-looking-for-beta-testers-1cm</guid>
      <description>&lt;p&gt;Hi 👋&lt;/p&gt;

&lt;p&gt;I’m a solo developer working on Ekit Studio, a developer-focused tool I built after years of rebuilding similar backoffice stacks for different projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why I’m building it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Across many web projects, I kept facing the same issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;structured content getting messy once multilingual is involved&lt;/li&gt;
&lt;li&gt;fragile template pipelines&lt;/li&gt;
&lt;li&gt;a lot of glue code between data, APIs, and rendering&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I eventually decided to standardize a single internal architecture and turn it into a standalone tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Ekit does (current beta)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project-based structured data (tables, records, fields)&lt;/li&gt;
&lt;li&gt;Multilingual content as a first-class feature&lt;/li&gt;
&lt;li&gt;Server-side rendering with custom templates&lt;/li&gt;
&lt;li&gt;Public API per project&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s still an early beta: the core is solid, but I’m actively refining UX and workflows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I’m looking for&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I’m looking for a few developers/makers willing to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;try it on a real or side project&lt;/li&gt;
&lt;li&gt;give honest feedback on onboarding and usability&lt;/li&gt;
&lt;li&gt;tell me what feels unclear, overkill, or missing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What you get&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Free beta access&lt;/li&gt;
&lt;li&gt;Direct feedback loop with the creator&lt;/li&gt;
&lt;li&gt;Real influence on the roadmap&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Beta available here: &lt;a href="https://ekit.app" rel="noopener noreferrer"&gt;https://ekit.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have questions, feedback, or want more technical details, I’ll be happy to discuss in the comments.&lt;br&gt;
Thanks for reading 🙏&lt;/p&gt;

</description>
      <category>devtools</category>
      <category>webdev</category>
      <category>backend</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>Filtering 13M Records at 2ms: Where to Draw the Line Between UX and Performance?</title>
      <dc:creator>Fabrice Grenouillet</dc:creator>
      <pubDate>Fri, 30 Jan 2026 04:18:22 +0000</pubDate>
      <link>https://dev.to/fabrice_grenouillet_c10f1/filtering-13m-records-at-2ms-where-to-draw-the-line-between-ux-and-performance-pg3</link>
      <guid>https://dev.to/fabrice_grenouillet_c10f1/filtering-13m-records-at-2ms-where-to-draw-the-line-between-ux-and-performance-pg3</guid>
      <description>&lt;h2&gt;
  
  
  Filtering 13M Records at 2ms: Where to Draw the Line Between UX and Performance?
&lt;/h2&gt;

&lt;p&gt;I’m currently building &lt;strong&gt;Ekit Studio&lt;/strong&gt;, a data-driven SaaS where users can manage dynamic schemas.&lt;br&gt;&lt;br&gt;
Naturally, I looked at tools like Airtable or Notion for inspiration.&lt;/p&gt;

&lt;p&gt;From a UX perspective, the dream is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I should be able to filter and sort on any field, instantly.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But when you're hitting &lt;strong&gt;13 million records&lt;/strong&gt; on a MongoDB collection, “instantly” becomes a real engineering constraint.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Context: A Scoped Architecture
&lt;/h2&gt;

&lt;p&gt;To keep things fast, the data is multi-tenant and always scoped.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Total records:&lt;/strong&gt; ~13M
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per scope:&lt;/strong&gt; ~4.4M (filtered by &lt;code&gt;project + proto + lang&lt;/code&gt;)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stack:&lt;/strong&gt; Node.js + MongoDB (running on a beefy Xeon)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To guarantee performance, I designed a &lt;strong&gt;slot-based indexing system&lt;/strong&gt;, mapping user-defined fields to a fixed set of indexed slots:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;4 string slots (&lt;code&gt;s1&lt;/code&gt;, &lt;code&gt;s2&lt;/code&gt;, &lt;code&gt;s3&lt;/code&gt;, &lt;code&gt;s4&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;1 number slot (&lt;code&gt;n1&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;1 date slot (&lt;code&gt;d1&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Only those slots are &lt;em&gt;guaranteed&lt;/em&gt; to be filterable and sortable at scale.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. The Surprising Benchmarks
&lt;/h2&gt;

&lt;p&gt;During stress tests, I noticed a clear divide in how MongoDB behaves with unindexed queries.&lt;/p&gt;

&lt;h3&gt;
  
  
  Small datasets (&amp;lt; 10k rows)
&lt;/h3&gt;

&lt;p&gt;Everything is basically “open bar”.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-field filtering&lt;/li&gt;
&lt;li&gt;Unindexed sorting&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;~10 ms max&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this scale, you don’t need a strategy — you just need a database.&lt;/p&gt;




&lt;h3&gt;
  
  
  Large datasets (~13M total / ~4.4M scoped)
&lt;/h3&gt;

&lt;p&gt;When queries are scoped using the main composite index (&lt;code&gt;project + proto + lang&lt;/code&gt;), results look like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pagination only (no filter, no sort):&lt;/strong&gt; ~1.2 ms
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unindexed “contains” filter (scoped):&lt;/strong&gt; ~2.2 ms
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pagination + contains filter:&lt;/strong&gt; ~2.0 ms
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Takeaway:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Unindexed filters, when scoped properly, stay acceptable much longer than I expected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The wall:&lt;/strong&gt; unindexed sorting.&lt;/p&gt;

&lt;p&gt;As soon as you try to sort millions of rows without an index, MongoDB hits its in-memory sort limits and performance collapses.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. The Strategy: “Performance Mode”
&lt;/h2&gt;

&lt;p&gt;Rather than punishing small users for the needs of large datasets, I’m leaning toward an &lt;strong&gt;adaptive UX&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Below 10k rows&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
→ open filtering and sorting on all fields (Airtable-like UX)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Above 10k rows&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
→ automatically enable &lt;strong&gt;Performance Mode&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
→ only indexed slots are available for filtering and sorting&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even in the “open” mode, there are guardrails:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;hard query timeouts (&lt;code&gt;maxTimeMS&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;no deep offset pagination&lt;/li&gt;
&lt;li&gt;no unbounded sorts&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. Lessons Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sorting breaks before filtering.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prefixes are king.&lt;/strong&gt; Always scope your queries.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UX vs engineering:&lt;/strong&gt; a restricted UX that actually works is better than a “free” one that freezes.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  I’d love to hear from you
&lt;/h2&gt;

&lt;p&gt;For those who’ve built similar systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where did you draw the line? 10k? 100k?&lt;/li&gt;
&lt;li&gt;Did you allow unindexed sorting early on?&lt;/li&gt;
&lt;li&gt;Have you tried on-demand or adaptive indexing?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m especially interested in real-world war stories.&lt;br&gt;&lt;br&gt;
Let’s discuss 👇&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>backend</category>
      <category>database</category>
      <category>saas</category>
    </item>
    <item>
      <title>Why I ran load tests before having users</title>
      <dc:creator>Fabrice Grenouillet</dc:creator>
      <pubDate>Sat, 24 Jan 2026 13:56:23 +0000</pubDate>
      <link>https://dev.to/fabrice_grenouillet_c10f1/why-i-ran-load-tests-before-having-users-4e1c</link>
      <guid>https://dev.to/fabrice_grenouillet_c10f1/why-i-ran-load-tests-before-having-users-4e1c</guid>
      <description>&lt;p&gt;When you’re building a dev tool, performance issues tend to show up at the worst possible time:&lt;br&gt;
right when users finally arrive.&lt;/p&gt;

&lt;p&gt;I’m currently building Ekit, a dev-first data engine / CMS, still in an early stage. I don’t have massive traffic yet — and honestly, I don’t need it. Even 100–500 real users would already be a win.&lt;/p&gt;

&lt;p&gt;Still, I decided to run load tests before traction. Here’s why — and what I learned.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why test before users?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most projects I’ve worked on (including my own in the past) followed this pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build features&lt;/li&gt;
&lt;li&gt;Get users&lt;/li&gt;
&lt;li&gt;Feel the app slow down&lt;/li&gt;
&lt;li&gt;Panic&lt;/li&gt;
&lt;li&gt;Try to fix performance under pressure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After 20+ years of development, I’ve learned that latency is much harder to fix once it’s already bad.&lt;/p&gt;

&lt;p&gt;So this time, I wanted answers early:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the architecture sane?&lt;/li&gt;
&lt;li&gt;Are there obvious bottlenecks?&lt;/li&gt;
&lt;li&gt;Can I onboard early users without stress?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Test setup (kept intentionally simple)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I used k6 to run basic load tests against the API and SSR endpoints.&lt;/p&gt;

&lt;p&gt;Nothing fancy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;realistic request patterns&lt;/li&gt;
&lt;li&gt;no artificial spikes&lt;/li&gt;
&lt;li&gt;focus on p95 latency, not just averages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal wasn’t to simulate massive scale, but to validate fundamentals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Results&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The most reassuring metric was the p95 latency ≤ 40 ms.&lt;/p&gt;

&lt;p&gt;That doesn’t mean the system is “ready for millions of users”.&lt;br&gt;
It simply means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;requests are fast&lt;/li&gt;
&lt;li&gt;the stack isn’t fighting itself&lt;/li&gt;
&lt;li&gt;there’s no obvious performance debt yet&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For an early-stage dev tool, that peace of mind is huge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What this changed for me&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Running these tests early had a very concrete impact:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I stopped worrying about infra during onboarding&lt;/li&gt;
&lt;li&gt;I could focus on product feedback instead of “will this hold?”&lt;/li&gt;
&lt;li&gt;I now know where the limits might be — before hitting them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Performance didn’t become a bragging point.&lt;br&gt;
It became a non-issue, which is exactly what you want.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I didn’t test (yet)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To be clear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I don’t have real production volumetry yet&lt;/li&gt;
&lt;li&gt;I haven’t tested extreme concurrency&lt;/li&gt;
&lt;li&gt;this isn’t a benchmark against other tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that’s fine.&lt;/p&gt;

&lt;p&gt;Load testing early isn’t about proving excellence —&lt;br&gt;
it’s about reducing uncertainty.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final thought&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If I had to summarize the lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It’s much easier to scale capacity later than to fix latency you ignored early.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’m curious:&lt;br&gt;
&lt;strong&gt;At what stage do you usually start load testing your projects — before users, or after?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>performance</category>
      <category>k6</category>
      <category>devtool</category>
      <category>saas</category>
    </item>
    <item>
      <title>A dev-first approach to managing multilingual content without rebuilding backends</title>
      <dc:creator>Fabrice Grenouillet</dc:creator>
      <pubDate>Fri, 23 Jan 2026 06:58:59 +0000</pubDate>
      <link>https://dev.to/fabrice_grenouillet_c10f1/a-dev-first-approach-to-managing-multilingual-content-without-rebuilding-backends-1eof</link>
      <guid>https://dev.to/fabrice_grenouillet_c10f1/a-dev-first-approach-to-managing-multilingual-content-without-rebuilding-backends-1eof</guid>
      <description>&lt;p&gt;I kept rebuilding backends for small multilingual websites, so I built a tool to stop doing that.&lt;/p&gt;

&lt;p&gt;I just recorded a few short demos showing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;structured multilingual content&lt;/li&gt;
&lt;li&gt;API access&lt;/li&gt;
&lt;li&gt;SSR preview and deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’d really appreciate feedback from other developers who’ve faced similar problems.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ekit.app/en/#section-videos" rel="noopener noreferrer"&gt;Link&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devtools</category>
      <category>webdev</category>
      <category>sideprojects</category>
      <category>multilingual</category>
    </item>
  </channel>
</rss>
