Work/04LOCKD/Keel

The swiss army knife for freelancers — engineered from first principles.

Enterprise-grade file delivery for freelancers — 5 GB uploads, watermarked previews, and self-enforcing access controls, all without a single background worker.

5 GB

uploads with zero background workers

lockd.zip ↗
LOCKD platform screenshot
Client
LOCKD
Industry
File Transfer / Productivity
Region
United Kingdom
Stack
Next.jsFastifyTypeScriptAWS LambdaS3SupabaseRailwayVercel

The Challenge

Freelancers live in a gap between consumer file sharing and enterprise platforms. Consumer tools like WeTransfer cap out at 2 GB, strip metadata, and offer no preview controls. Enterprise solutions like Hightail or Aspera are built for post-production studios with IT departments — not a solo photographer sending proofs to a client.

LOCKD needed to bridge that gap: handle the file sizes and preview requirements of professional creative work, but with the simplicity of a consumer tool. No onboarding flow. No seat licenses. No IT department required.

The platform needed to:

  • Handle files from kilobytes to multiple gigabytes without timeouts or memory issues
  • Generate watermarked previews for both images and video without blocking the upload flow
  • Create downloadable ZIP archives for multi-file transfers without background job infrastructure
  • Support file requests — letting clients upload directly into a branded portal

The hard constraint: no background job infrastructure. No Redis, no Bull, no persistent workers. Every async operation — from watermarking to ZIP creation — had to be handled through Lambda functions with a callback webhook pattern, keeping the core API lean and stateless.

The Solution

01

Three-Tier Upload Strategy

A single upload strategy can't serve files that range from a 200 KB logo to a 4 GB video master. Small files need to be instant. Large files need resilience. Edge cases need a fallback that doesn't crash.

The system inspects file size at selection time and routes each file through the appropriate path automatically:

  1. 01

    Presigned Upload

    Files under 50 MB are uploaded directly to S3 via a presigned PUT URL — a single request, zero server load.

  2. 02

    Chunked Multipart

    Files between 50 MB and 5 GB are split into 25 MB chunks, uploaded in parallel, and reassembled by S3. Failed chunks retry automatically.

  3. 03

    Streaming Fallback

    For edge cases where presigned URLs aren't viable, the server proxies the upload as a stream — never buffering the full file in memory.

The user never sees this complexity. They drag a file, it uploads. The system decides how.

One drag. Three strategies. Zero config.

Upload tiers
Direct to S3Fallback
Browser
Size Check
Routes each file by size
Three paths
Presigned Upload
Direct PUT to S3 — single request
< 50 MB
Chunked Multipart
Parallel 10 MB parts with resume
50 MB – 5 GB
Streaming Fallback
Server-proxied stream for edge cases
Fallback
S3 Storage
The upload strategy is selected automatically based on file size — no user intervention required.
02

Streaming ZIP Creation

When a recipient wants to download all files at once, the platform needs to produce a ZIP archive — potentially gigabytes in size. Traditional approaches buffer the entire archive in memory or on disk. Neither scales when archives can reach multiple gigabytes.

Instead, a Lambda function streams files directly from S3 into a ZIP stream that writes back to S3 as it goes. No intermediate buffer. No disk. The function's memory footprint stays constant regardless of total file size.

  1. 01

    Request

    The client selects files and requests a ZIP. The API validates access and invokes a Lambda function.

  2. 02

    Stream & Compress

    The Lambda streams each file from S3 and compresses on-the-fly — no intermediate disk or memory buffer.

  3. 03

    Stale Detection

    If source files change during creation, the operation aborts and the client is prompted to retry.

  4. 04

    Delivery

    The completed ZIP is written to S3 and a presigned download URL is returned to the client.

Gigabytes compressed without touching the API server.

Streaming ZIP creation
LambdaDoneAbort
  1. 01
    API Request
    Client requests ZIP for selected files
  2. 02
    Lambda Invocation
    Serverless function streams files from S3
  3. 03
    Streaming ZIP
    Files compressed on-the-fly, streamed to S3
  4. 04
    ZIP Ready
    Presigned download URL returned to client
source changed
Guard
Stale Detection
If the source files change after ZIP creation begins, the operation is aborted and the client is notified to retry — preventing inconsistent archives.
ZIP creation runs entirely in Lambda — no server infrastructure to manage or scale.
03

Async Watermarking Pipeline

Freelancers need to share previews without giving away the originals. Watermarked previews solve this — but generating them synchronously during upload would make the experience painfully slow, especially for video.

The watermarking system runs as an asynchronous pipeline. Uploads complete instantly. Preview generation kicks off in the background across two specialised paths:

  1. 01

    Upload completes

    The user receives immediate confirmation. Watermarking begins asynchronously.

  2. 02

    Image pipeline

    A dedicated Lambda downloads the original from S3 and uses FFmpeg to composite the watermark overlay — typically under 5 seconds per image.

  3. 03

    Video pipeline

    FFmpeg generates a preview clip and burns in the watermark. A shared Lambda layer keeps the binary under 50 MB.

  4. 04

    Preview ready

    Watermarked previews are stored alongside the originals. The UI updates automatically when processing completes.

Previews without giving away the originals.

Watermark pipeline
PipelineShared layerOutput
Image pipeline
Source Image
Resize
Scale to preview dimensions
Watermark
Overlay with Sharp
Shared
Shared Lambda Layer
FFmpeg Binary
Video pipeline
Source Video
Transcode
Generate preview clip
Watermark
Burn-in overlay
Watermarked Preview Ready
Both pipelines share a single FFmpeg Lambda layer — keeping cold starts under 2 seconds.
04

File Requests & Collaborative Preview

Sharing files is only half the workflow. Freelancers also need to collect files from clients — brand assets, content for editing, signed contracts — and get feedback on deliverables before final handoff.

File Requests generate a branded upload portal with a unique link. The client uploads directly — no account required. Files land in the freelancer's transfer, organised and ready for download. The upload portal inherits the sender's branding: logo, colours, and a custom message.

Collaborative Preview turns any transfer into a review surface. Recipients can view watermarked previews in a gallery and leave threaded comments on individual files — including timestamp-linked feedback on audio and video (e.g. “at 2:34, the transition feels abrupt”). No account required — commenters just provide a display name. The freelancer sees all feedback in one place — no email chains, no scattered messages.

05

Access Control & File Lifecycle

Files shouldn't live forever. Every transfer in LOCKD has a lifecycle governed by four independent controls — each enforced at the API level, not the frontend.

Expiry timers auto-disable access after 24 hours, 7 days, or 30 days. Download limits cap the number of times each recipient can access a file. Password protection adds an optional passphrase gate. And when any condition triggers, auto-cleanup purges the files from S3 entirely — not just the links.

The result is a system where files are available exactly as long as they need to be, and not a second longer. The audit trail — who accessed what, when, how many times — is preserved even after the files are gone.

Transfer lifecycle
LimitsGatePurge
Enforced at the API
Expiry Timer
Auto-expire after 24h, 7d, or 30d
Access Limits
Max download count per recipient
Password Protection
Optional passphrase for file access
Auto-Cleanup
Files purged from S3 on expiry
any trigger
Final state
Expired Transfer
Files removed, access revoked, audit trail preserved
Every control is enforced at the API level — the frontend only reflects the current state.
06

MIME Detection & Structured Errors

Two foundational systems run beneath every feature: content-based file type detection, and a structured error framework.

MIME detection reads magic bytes from the file header rather than trusting the uploaded file extension. A file named photo.jpg that's actually a PDF will be identified correctly — and routed to the right preview renderer. This prevents spoofing, ensures correct thumbnails, and means the watermarking pipeline always knows what it's processing.

Structured errors ensure every API endpoint returns a typed, machine-readable error object with a stable error code and a human-friendly message. The frontend maps these to contextual UI — a file too large shows the size limit, an expired transfer shows when it expired, a rate-limited request shows when to retry. No generic “something went wrong” modals.

Technical Architecture

Frontend
Next.js 15 / React 19 / TypeScript / Tailwind CSS
Backend
Fastify 5 / AWS Lambda
Database
Supabase (PostgreSQL + Row-Level Security)
Auth
AWS Cognito (JWT / RS256 / JWKS)
Storage
AWS S3 (presigned URLs + multipart upload)
Media Processing
FFmpeg Lambda Layer (images + video)
ZIP Generation
AWS Lambda (streaming compression)
Payments
Stripe Payment Links (file unlock)
Email
Resend API + React Email
Hosting
Vercel (frontend) / Railway (API)

Key Architecture Decisions

Rather than a single upload strategy, the system selects from presigned PUT, chunked multipart, or streaming fallback based on file size. This keeps small files instant while supporting multi-gigabyte uploads without timeout or memory issues.

Key Features

Large file uploads

Multi-gigabyte files via chunked multipart with automatic resume

Watermarked previews

Image and video previews with burned-in watermarks

Bulk ZIP download

Lambda-powered ZIP creation streamed directly from S3

File requests

Request files from clients with branded upload portals

Collaborative preview

Share preview links with comments and approval workflow

Access controls

Expiry, download limits, and password protection per transfer

Pay-to-unlock

Gate file access behind Stripe payment links

MIME detection

File type identified from magic bytes, not extensions

Responsive UI

Full mobile support for uploading, previewing, and downloading

Structured errors

Typed error responses with stable codes and contextual UI

Transfer analytics

Track views, downloads, and access patterns per transfer

Custom branding

Upload portals and preview pages match the sender's brand

Need a platform that handles large files without compromises?

Whether you need multi-gigabyte uploads, async media processing, or secure file delivery — we'd love to talk.

Start a project
Next project
A Jewellers
Luxury retail · E-commerce
→