jp ferreira
← All projects
Freelance

Kardz

A digital greeting card and media-sharing platform with rich photo galleries, video generation, and asynchronous media processing.

Role
Full-Stack Engineer
Period
2023 – 2024

// 01

Problem

Kardz was built around the idea that digital greeting cards and shared media experiences are often either too generic, too static, or unnecessarily fragmented. Traditional e-cards typically offer limited personalisation, while sharing photos and videos from meaningful events often requires a patchwork of messaging apps, cloud storage links, and social platforms that were never designed specifically for curated shared experiences.

The goal of Kardz was to create a more engaging digital product where users could create and share rich greeting card experiences that included personalised messaging, photo galleries, and video content in a polished, purpose-built environment. Instead of simply sending an image or text message, users could deliver something closer to an interactive digital keepsake.

From a product perspective, the challenge was combining emotionally-driven user experience design with technically demanding media workflows. Supporting images is straightforward at small scale, but once users begin uploading multiple high-resolution photos, generating videos, browsing galleries, and expecting smooth performance across devices, the complexity grows quickly. Kardz was designed to solve that while maintaining a responsive and intuitive user experience.

// 02

Technical Approach

Kardz was architected as a full-stack web application with a Ruby on Rails backend and a React frontend written in TypeScript, with a strong emphasis on media processing, asynchronous workflows, and performance optimisation.

Ruby on Rails was chosen because it allows rapid product iteration while still providing a mature framework for modelling users, cards, media assets, permissions, API endpoints, and business workflows. PostgreSQL was used as the primary relational database, while Redis and Sidekiq handled asynchronous background processing. This became particularly important for heavier workloads such as video generation and media transformation, where synchronous request processing would create poor user experience and server bottlenecks.

On the frontend, React with TypeScript was used to build a dynamic and responsive interface for creating cards, browsing image galleries, managing uploads, and interacting with shared content. Media assets were stored in AWS S3 via Active Storage, while FFmpeg was integrated for video processing workflows. As media usage increased, performance optimisations became critical. Pagination was introduced for gallery endpoints to reduce payload size and bandwidth consumption, image listing strategies were reviewed for caching opportunities, and media-heavy operations were intentionally shifted into background jobs.

The architecture intentionally balanced rapid product development with realistic production concerns such as storage cost, asynchronous reliability, scaling constraints, and API responsiveness.

// 03

Interesting Hard Bits

The most interesting engineering challenges in Kardz centred around media-heavy workflows and performance trade-offs. Building a CRUD application is one thing; building a system that handles user-generated images and video at scale introduces a very different class of problems.

One particularly challenging area was video generation. Users could upload content that required server-side transformation, including FFmpeg-based conversion and processing before storage. Running this synchronously quickly became impractical, so the workflow was moved into background processing with Sidekiq. That required thinking carefully about infrastructure limitations, job execution time, reliability, storage behaviour, and user experience expectations while processing completed asynchronously.

Another rewarding challenge was performance optimisation. Image galleries initially worked fine at smaller scale, but as the number of uploaded assets grew, payload sizes and response times became increasingly problematic. Implementing pagination across backend APIs and frontend consumers significantly improved performance, while prompting broader thinking around caching, bandwidth cost, and future scalability.

What I'm most proud of is that Kardz pushed me into real-world engineering decisions rather than purely feature delivery. It required balancing user experience, infrastructure cost, asynchronous design, and system scalability - the kinds of trade-offs that make production engineering genuinely interesting.

Tech Stack

Frontend

ReactTypeScriptJavaScript

Backend

Ruby on Rails

Database

PostgreSQL

Background Jobs

SidekiqRedis

Media Processing

FFmpegActive StorageAWS S3

Highlights

Performance work

  • Pagination on gallery API endpoints to reduce payload and bandwidth
  • Media-heavy operations moved to background jobs (Sidekiq)
  • Caching strategy review for image listing