Anton Bohachuk
← ALL WORK

Coverr

Stock media platform for video creators, with an AI Studio for generating media on demand.

Type
Product
Year
2023 — Present
Duration
2 years 9 months
Team
6 people
Coverr
Context

Coverr is a stock media library: free video, music and — since 2025 — images, used mainly by marketers, designers and small studios. Most of the revenue doesn't come from Coverr's own catalogue: results are blended with partner inventory from Shutterstock or Getty Images, and a click through to a partner is what pays for the site. Traffic is global and almost entirely search-driven, which makes page speed and SEO a revenue question rather than a polish question.

I joined a team of six — a tech lead, two full stack engineers, a designer and two stakeholders — just as generative media became viable. Most of my three years went into AI Studio: a subscription product built on top of the existing library, shipped feature by feature, alongside the infrastructure and analytics work the rest of the site needed.

Problem

Almost all of Coverr's revenue came from partner referrals — Shutterstock or Getty inventory blended into search results. That worked, but it made the business dependent on agreements it didn't control: if a partnership ended, so did most of the income. The stakeholders wanted a line of revenue that belonged to Coverr, which meant finding something users would pay for directly.

Generative media was just becoming viable at the time, and the audience already matched — people arriving for stock footage want assets now, and generation answers that better than a catalogue can. The bet was to give them an interface for it: video, images, music, voiceovers and sound effects, generated on demand, behind a subscription. That reframed the engineering problem from serving a static library to running a product on top of third-party generation providers.

Stack

An Nx monorepo with an Angular client on NGXS and RxJS, server-rendered at the edge by Cloudflare Workers. The API is NestJS on Cloud Run, talking to PostgreSQL through TypeORM with Redis caching on the hot endpoints; heavier work is handed off over Pub/Sub to a set of small Cloud Run Functions that reach the same database through Knex. Media lives in Google Cloud Storage, and generation runs against fal.ai, OpenAI, Gemini, Vertex and Cloudflare AI.

REQUEST PATH
Browser
coverr.co
SSR + CDN CACHE AT EDGE
Cloudflare Workers
Angular SSR · CDN cache
Angular SPA
NGXS · RxJS
NestJS API
Cloud Run · TypeORM · Redis cache
PUB/SUB
Subscriptions
Cloud Run Functions
Translations
Cloud Run Functions
Video
Cloud Run Functions
Data base
PostgreSQL · TypeORM · Knex
Media storage
Google Cloud Storage
Generation APIs
fal.ai · OpenAI · Gemini · Vertex
TypeScriptAngularNGXSRxJSNxNestJSTypeORMPostgreSQLRedisCloud RunPub/SubCloud StorageCloudflare WorkersPostHog
Decisions

Free credits before the paywall

Subscriptions were the whole point of AI Studio, which made it tempting to put generation entirely behind them. I argued for the opposite: a pool of free credits and a set of cheaper models available without paying. Nobody subscribes to an interface they haven't watched produce something, and the free tier turned the paywall from a promise into a trial.

One model config, validated twice

Every provider takes different parameters, and each one has its own required fields, allowed values and media inputs. Rather than encode that per provider in two places, each model has a configuration edited through the admin panel that drives both the browser-side form validation and the server-side check. Adding a provider is a config entry, not a release.

Copy the media before the provider deletes it

Providers return a URL on their own domain and typically clear generated files after a day. Left alone, a user's library would quietly break overnight. Once a generation succeeds, a handler pulls the file into our own storage and swaps the URL in place — nothing changes for the user, the asset just stops depending on someone else's retention policy.

Generated media enters the same pipeline as uploads

Coverr already had processing for footage submitted by videographers: metadata extraction, then a pass that generates title, description and tags. Generated video runs through exactly that pipeline rather than a parallel one, so anything a user creates arrives fully described and ready to enter the catalogue if we ever decide to publish it.

Outcome
~2s~1s
LCP on catalogue pages after edge migration
Cloud RunWorkers
hosting cost cut ~85%
~4×
subscription MRR after AI Studio shipped
baseline+100%
purchase completion, best experiment variant

Checkout initiation rose 80% in the same set of experiments, and the localization pipeline now covers seven languages without a per-locale release.

Trade-offs

The edge runtime constrains what the frontend can depend on. Every library that reaches for a Node built-in has to be replaced or shimmed, and debugging a Worker is meaningfully worse than debugging a container. That cost is paid on every new dependency, not once during the migration.

Edge caching and personalisation don't coexist easily. A page rendered for a signed-in user can end up in the CDN and be served to someone else, so SSR always returns the anonymous version — the client then checks for a token and swaps into the signed-in state behind a loading state. It's correct, but it means the first paint is never the real page for the people who use the site most.

Seven languages made shipping copy expensive. Any new string means the original plus six translations through the admin panel, and while translation is automated, the output still needs review: capitalisation drifts, trailing punctuation appears or disappears, and a word that fits a button in English arrives twenty characters long in German. Adding a locale is cheap now; adding a sentence isn't.

Contact

Let's talk

Open to full stack roles, remote or on-site in Varna. The fastest way to reach me is email or Telegram.

ANTON BOHACHUK · VARNA, BULGARIA (EET)© 2026