This is a submission for the MLH x DEV Writing Challenge
What I Built
The Problem With How We Learn Words
You're reading something. You hit a word you don't know. You look it up, nod, and move on.
Three days later, you see the same word.
You look it up again.
This has happened to me more times than I'd like to admit, and I speak English fluently. The problem isn't finding the meaning of a word. It's remembering it well enough to actually use it later.
Looking something up and learning it are two completely different things.
I once tried paper flashcards. I made 10 cards from two pages of a book. I've had a lot of books. The stack grew faster than I could review it, and eventually the flashcards became clutter on my desk rather than something I actually used.
So when MLH's Global Hack Week: Data, a week-long challenge featuring Tiger Cloud as the partner technology, came up, I had a clear idea of what I wanted to build.
Not because it was the most impressive project I could think of, but because it was something I actually needed.
I built EchoCadence, a spaced-repetition vocabulary app where you add your own words, review them, and let the scheduling algorithm determine when each card should come back.
Check it out here: EchoCadence
Who Is This For?
EchoCadence is for anyone who knows the frustrating feeling of recognizing a word but not being able to remember it when they need it.
Maybe you're trying to level up in a language you already speak. You know what sanguine, perfidious, or equivocate mean when you see them, but you want those words to become part of your active vocabulary.
Or maybe you're learning a completely new language and need somewhere to collect the words you encounter.
The use case is the same:
Learn a word once, then revisit it at customized intervals to reinforce it and retain it for the long term.
That's what EchoCadence is built around.
How EchoCadence Works
The user flow is deliberately simple:
- Sign up with Google or email.
- Choose a language from a broad range of supported languages. You can work with multiple languages at the same time, up to seven.
- Add vocabulary using built-in categories, or create custom categories with your own fields.
- Learn new cards. Flip a card, check your answer, and rate how difficult it felt.
- Revise cards that are due for review based on their previous review history.
- Track your progress through weekly review statistics, difficulty level, next-review dates, and first-attempt performance.
The distinction between Learn and Revise is intentional.
Learn is where new vocabulary enters the system. Revise is where the repetition happens.
After a card is reviewed, EchoCadence updates its scheduling information, including its interval and ease, and uses that state to determine when the card should appear again.
The goal isn't to make you review everything every day.
It's to turn a growing list of vocabulary into a review schedule you can actually follow.
What I Learned Building This
I didn't use an AI API to decide what a learner should study next. There isn't a recommendation model hiding behind the interface.
The core scheduling logic is based on a classic spaced-repetition approach, while the rest of the system is built around something much less glamorous:
Getting the data model right.
A vocabulary app doesn't just need to store words.
It needs to remember what happened to each card: when it was reviewed, how it was rated, how its scheduling state changed, and when it should be seen again.
That made the database more interesting than I initially expected.
And that's where Tiger Cloud came in.
Instead of treating every review as just another row in a generic table, I modeled reviews as time-oriented events. The card_reviews table stores those review events with timestamps, and I converted it into a TimescaleDB hypertable.
I also created a continuous aggregate that groups review data into daily buckets and calculates review statistics such as total reviews, correct and incorrect answers, and average response-related metrics.
Demo
Try EchoCadence live here: EchoCadence
See EchoCadence in action:
A few glimpses of the experience, from learning new words to tracking what actually sticks.
Want to see it in motion?
Partner Technologies
EchoCadence was built for MLH Global Hack Week: Data event- 2 challenges, both using Tiger Cloud by Tiger Data:
- Set up a Tiger Cloud service and create your first Hypertable
- Accelerate Dashboards with Continuous Aggregates
The interesting part was that both challenges mapped naturally onto something EchoCadence already needed: remembering what happens every time someone reviews a flashcard.
Tiger Cloud gave me a managed PostgreSQL database with TimescaleDB capabilities built in. I could connect to it using a regular PostgreSQL connection string, keep using SQL from my application, and add TimescaleDB features where they actually made sense.
That meant I didn't have to build a separate time-series storage layer just for the hackathon. I could keep the application's existing PostgreSQL model while treating review history as time-series data.
And that became the data foundation for both challenges.
Challenge 1: The Hypertable: Turning Reviews Into Time-Series Data
Every time a learner reviews a flashcard, EchoCadence records that event in card_reviews.
A review isn't just another piece of vocabulary data. It has a when:
- when the review happened
- which card was reviewed
- which user reviewed it
- whether the answer was correct
- how the user rated the difficulty
- response/review-related metrics
That makes the review log naturally time-oriented.
I created card_reviews as a normal PostgreSQL table and then converted it into a TimescaleDB hypertable using:
SELECT create_hypertable(
'card_reviews',
'time',
if_not_exists => TRUE
);
The important part here is the time column.
From my application's perspective, card_reviews still behaves like a PostgreSQL table. My backend can continue inserting and querying review records using SQL. TimescaleDB handles the time-based organization underneath by partitioning the hypertable into chunks.
So I didn't have to redesign the application around a completely different database.
The application thinks in reviews. TimescaleDB can think in time.
That was particularly appropriate for EchoCadence because review history will naturally grow as learners keep using the application. The data isn't just a static collection of vocabulary, it's an ever-growing chronological record of learning activity.
Some snapshots of my Tiger Data Console, showcasing my hypertables:-
Challenge 2: Continuous Aggregates: Turning Review Events Into Statistics
The second challenge was where the review history became useful for analytics.
I created a continuous aggregate called daily_review_stats over the card_reviews hypertable:
CREATE MATERIALIZED VIEW daily_review_stats
WITH (timescaledb.continuous) AS
SELECT
user_id,
time_bucket('1 day', time) AS day,
COUNT(*) AS total_reviews,
SUM(CASE WHEN correct THEN 1 ELSE 0 END) AS correct_count,
SUM(CASE WHEN correct THEN 0 ELSE 1 END) AS incorrect_count,
AVG(response_time) AS avg_response_time,
AVG(rating) AS avg_rating
FROM card_reviews
GROUP BY user_id, day
WITH NO DATA;
Instead of looking at every individual review event when I want daily-level information, this aggregate organizes the data into one-day buckets and calculates useful statistics for each user.
The key TimescaleDB feature here is:
WITH (timescaledb.continuous)
And the time bucketing comes from:
time_bucket('1 day', time)
This is where the two challenges connect nicely:
Hypertable: stores the growing stream of review events
Continuous aggregates: turns those events into time-based analytical summaries
Some Snapshots from TigerData console, showcasing my CAGGs:-
Why Tiger Cloud Made This Easier
The biggest advantage for me as a solo builder was not having to manage the database infrastructure myself during a one-week hackathon.
Tiger Cloud gave me the hosted TimescaleDB environment and connection details I needed. I could focus on the actual application, rather than spending the hackathon setting up and maintaining the database environment.
And because TimescaleDB extends PostgreSQL rather than replacing it, I didn't have to learn an entirely different database programming model just to use time-series functionality.
I could still write normal SQL.
Then, when I had a genuinely time-oriented problem, I could use TimescaleDB-specific functionality:
create_hypertable(...)
and
time_bucket(...)
with
WITH (timescaledb.continuous)
That was probably my biggest takeaway from working with Tiger Cloud:
I didn't have to force my application into a time-series database. I found a part of the application that was already time-series data.
For EchoCadence, that's the review history.
The vocabulary is what the learner sees.
The review history is what the application remembers.
Other Technologies & Algorithms I Used
1) Auth0: Authentication Without the Rabbit Hole
Authentication is one of those things that looks simple until you're three hours deep into OAuth flows, tokens, and session handling.
I used Auth0 for authentication, session persistence, and the first-login username setup. The frontend is wrapped in Auth0Provider, while authenticated API requests send the user's token in the Authorization header.
I also added a client-side 15-min inactivity timeout that resets with user activity.
Auth0 handled the authentication infrastructure; I focused on making the flow fit naturally into the application.
2) SM-2-Style Spaced Repetition: The Learning Logic
EchoCadence doesn't use an AI model to decide when a word should come back.
Instead, its review scheduler uses an SM-2-style spaced-repetition algorithm. Each card maintains scheduling state such as its ease factor and review interval. A user's rating changes that state and determines when the card should appear again.
Difficult cards are brought back sooner, while cards that are consistently easier can move to longer intervals.
Hackathon Experience
Global Hack Week: Data was an online, week-long challenge by MLH. I wasn't able to attend most of the livestreams live, but I followed along with the sessions & days' agenda as much as I could. I also watched the Tiger Cloud sessions on YouTube, alongside what I already knew from using TigerData in a previous hackathon.
I built EchoCadence completely solo, from the idea and implementation to the database design and deployment. This was my first hackathon after a really long break, so it was nice to get back to building and, especially, to put some of the SQL I'd been practicing into an actual application instead of another exercise.
What I'll remember most is that I didn't build EchoCadence just to have something to submit. I've already started using it to save words I want to remember. There's something genuinely satisfying about building a tool and then realizing you actually need the tool you built.
I'm also glad to be back on DEV.to. It's been a while.
Conclusion
EchoCadence started with a small frustration: looking up the same word over and over again and still not remembering it when I actually needed it.
I wanted to build something that could turn that frustration into a habit, somewhere I could collect the words I encounter, learn them, and let spaced repetition decide when they should come back. Building it also gave me a chance to take something I'd been learning: SQL and data modeling, and use it in a real application.
If you've ever had a word you know you've seen before but somehow can't remember, give EchoCadence a try. Add a few words that you genuinely want to keep, come back when they're due, and see whether they stick.
Built solo. No AI APIs. Just a vocabulary problem, a spaced-repetition algorithm, and a database that remembers what happened.
Thank You
If you've made it all the way here, thank you for reading till the endπ₯Ήπ₯Ή
Thank you to @mlhacks for "Global Hack Week: Data" and for creating the challenge that gave me a reason to build EchoCadence. And thank you to @thepracticaldev for this platform, which gave me the opportunity to participate, build in public, and come back to a community I've missed being a part of.
And if you end up trying EchoCadence, I hope one of those words you've been meaning to remember finally sticks.











Top comments (5)
Nice Divya :D
Thank you for checking it out π₯Ή
Wishing you all the best and hoping for your victory. Warm regards from Divya to Divya!
really solid project. definitely worth checking out π
Thank you Vaibhav!