Initializing, please wait a moment

What we learned running free in-browser image tools for 100K monthly users


freetoolonline.com ships ~100 web utilities - HEIC converters, PDF tools, device tests, developer utilities - as static HTML pages with WebAssembly for the heavy lifting. No sign-up, no upload, no server-side processing. In a representative recent month, the site served ~100,000 monthly users across ~130 countries, ~1.35 million page impressions, and a few terabytes of browser-side wasm processing. This piece covers the architectural decisions that hold at that scale, the things we got wrong and fixed, and the surprises that don’t show up in any tutorial.


The shape of the traffic

Cluster by cluster, traffic is hugely uneven. ZIP tools alone account for ~81% of site clicks - one specific tool, unzip file, is the single biggest source of inbound search traffic, dwarfing the other 99 tools combined. The second tier is image conversion (HEIC to JPG leads), device tests (LCD test leads), and PDF tools (remove-password leads). Developer tools and video tools are long-tail. See our tags index for the full cluster breakdown.

Geographic distribution is similarly skewed. India produces ~35% of clicks at ~12% CTR; the US produces ~30% of impressions but only ~1% CTR. The same tool - HEIC to JPG - behaves completely differently in US SERPs (where iPhone users expect premium-looking answers) vs Indian SERPs (where utility and speed wins).


Why everything runs in the browser

Every tool is implemented in-browser via WebAssembly + JavaScript. There’s no backend that processes user files. The reasons are practical, not ideological:

Privacy is the marketing. “Your files never leave your device” is a promise a server-backed tool cannot make at any scale. Users landing on a HEIC-to-JPG page with photos of their ID card, their lease, their medical bills - they read that claim before they click.

Cost scaling is the opposite of what you’d think. A server-backed conversion service at 100K monthly users would require non-trivial compute, storage, and bandwidth. The in-browser architecture has fixed cost (the static HTML + JS + wasm bundles served from GitHub Pages CDN, approximately $0/month). The user’s device does the work.

Scale-to-zero is the default. Zero traffic = zero cost, zero running services, zero security surface. Millions of impressions = same zero cost because it’s all CDN-cached static files plus user CPU.


What breaks at each traffic tier

At ~1,000 monthly users, nothing breaks. The wasm bundles fit in the browser, tools work, the site deploys with GitHub Actions. Rapid iteration matters more than anything else.

At ~10,000 monthly users, SEO starts to matter. The tools are good; nobody finds them. Title and meta description rewrites (lead with the exact query the user typed) move traffic by 2–5×. See our JPG vs PNG and other comparison guides for the pattern - each is a sibling to a tool, authored to capture the upper-funnel query that the tool alone doesn’t rank for.

At ~100,000 monthly users, schema and E-E-A-T signals start showing up in the traffic data. Pages with HowTo or FAQPage JSON-LD have measurably higher CTR than pages without. An editorial byline and “Why trust us” block on hubs feed the E-E-A-T side of Google’s Helpful Content posture; monthly cluster impressions rose ~15% after we added that surface.

At higher scales, the growth ceiling is no longer SEO; it’s cross-cluster link equity and external backlinks. We haven’t hit that ceiling; Semrush shows us at ~30 referring domains, most organic, none from active outreach. The next phase for us is that outreach.


The five things we got wrong and fixed

1. First-paint was hidden behind a loading overlay. Our base template put a full-screen “Initializing, please wait” overlay on every page until the JS finished loading. On /guides/* pages (which don’t need tool-UI JS), the overlay stayed forever - users saw a blank page. The fix: make overlay-dismiss logic live in the base template, not in each tool’s script, so every page kind dismisses the overlay uniformly.

2. Heading hierarchy leaked from tool-UI widgets. Several tool pages (LCD test, MD5 converter, GIF maker) had <h3> or <h6> widget labels rendered before the page’s <h1>. Accessibility tools flagged it as a hierarchy error; SEO audit tools flagged it as topical-signal weakness. The fix: demote widget labels to <p> with CSS to preserve visual weight. Simple but widely overlooked.

3. FAQ JSON-LD silently dropped on some pages. Our schema extractor matched FAQ sections by the literal heading “Frequently Asked Questions.” A few FAQ sections used “FAQ:” or “FAQs” instead; their FAQPage schema never emitted. The fix: broaden the extractor regex. The bug was a single-character-class change; the impact was 4 tool pages regaining rich-result eligibility.

4. Alias routes leaked into GSC as “duplicate content.” Short alias URLs (e.g., https://freetoolonline.com/video-converter.htmlhttps://freetoolonline.com/video-converter.html) emitted a noindex, nofollow, which is technically correct but wastes the alias’s link equity. Switching to noindex, follow passed the equity to the canonical without risking duplicate indexing. Small change; material equity recovery.

5. Staging and production drifted. Our staging repo lives on GitHub Pages (dangkhoaow.github.io/freetoolonline-web-test); production lives on freetoolonline.com backed by a separate GitHub repo. A dedicated mirror process keeps the two in sync. At one point we had 20+ commits on staging not mirrored to production - the site was serving pre-release content. The fix: a written mirror contract (which files, which branches, which never-copy rules) and a regular audit.


What the wasm budget actually looks like

Modern browsers give a tab ~4 GB of heap on desktop and ~1–2 GB on mobile. After the wasm code, JIT, and UI consume their share, a wasm tool has ~1–2 GB to work with. Reality for each tool family:

  • HEIC conversion: 40 MP photo decodes in ~150 MB of working memory; dozens of files per batch fit comfortably. 500 files in one batch can OOM.
  • PDF manipulation: A 100-page PDF rendered page-by-page is fine; a 500-page PDF loaded into a single buffer for re-encoding frequently fails on mobile.
  • FFmpeg video conversion: 1080p 60-second clip transcodes in ~600 MB; anything longer or higher-resolution is the limit.
  • Image minification / compression: Essentially no limit - the CPU is the bottleneck.

We message these limits clearly on each tool page. A user who picks a 5 GB video and sees “this may fail” warnings before clicking Start is a user who doesn’t file a support request.


Three counter-intuitive observations

Mobile CTR is higher than desktop, not lower. The common web wisdom is that mobile users skim and don’t click. Our data shows the opposite on tool pages: mobile CTR is ~6.7% vs desktop’s ~5.6%. The hypothesis: mobile searchers are more often in a “solve this now” mindset (just snapped an iPhone photo, needs it as JPG) vs desktop searchers in exploration mode.

Long-tail is most of the value, even for a tools site. The top 10 tools account for 80% of impressions but only ~60% of clicks. The long tail (50 tools at 500–5,000 impressions each) converts at higher CTR because the query specificity is higher. Do not deprecate a tool because it’s low-impression.

Schema improvements pay off in weeks, not months. HowTo JSON-LD, FAQPage, BreadcrumbList - adding these to a page consistently moves CTR by 0.3–0.8pp within 2–3 weeks of Google re-crawling. The same content without schema waits 2–3 months for SERP position improvement to translate to click volume.


What we still haven’t solved

US CTR (1.09%) remains an order of magnitude behind India (12%). We’ve rewritten titles and descriptions in US-first language; the gap narrows slowly. We suspect the US SERP is more competitive - more tools competing for the same query - not that our pages are worse in absolute terms.

AdSense RPM varies 50% month-to-month with no visible cause. Geographic mix shifts, cluster mix shifts, placement experiments - none fully explain the variance. The revenue side of the site is less predictable than the traffic side.

Referring-domain growth is stuck at ~30 domains. Outreach has not been a priority; the next phase for the site is changing that.


What we’d recommend to anyone building similar

Ship static pages with wasm for the heavy lifting. Reject the urge to add accounts, quotas, or premium tiers - they’re usability tax without matching revenue. Do privacy with the architecture (nothing uploads) rather than marketing (“we don’t log”). Write the SEO content as if you’re the user’s friend explaining the task, not as if you’re the tool’s marketing department. Measure cold-start, parse time, and first-paint on real devices, not local dev.


Related guides


← Back to Home

Why trust these tools

  • Ten-plus years of web tooling. The freetoolonline editorial team has shipped browser-based utilities since 2015. The goal has never changed: get you to a working output fast, without an install.
  • Truly in-browser - no upload. Every file-processing tool on this site runs in your browser through modern Web APIs (File, FileReader, Canvas, Web Audio, WebGL, Web Workers). Your photo, PDF, audio, or text never leaves your device.
  • No tracking during tool use. Analytics ends at the page view. The actual input you paste, drop, or capture is never sent to any server and never written to any log.
  • Open-source core components. The processing engines underneath (libheif, libde265, pdf-lib, terser, clean-css, ffmpeg.wasm, and others) are public and audit-able. We link to each one in its tool page's footer.
  • Free, with or without ads. All tools are fully functional without sign-up. The Disable Ads button in the header is always available if you need a distraction-free run.