We would want to have 2 types of APIs - one API would serve to get the request and the URL.
The API would redirect the sender to the actual resource and on success return 302 (redirected) or fail on something like 404
The other API would let the user encode their URL in the UI portal. We should allow them to specify the URL themselves which can be hashed easily to locate where the URL is stored
The ideal database for this system would be key-value value based. Because each URL will have a unique hash we can use that as our key. A NoSQL database like DynamoDB would work perfectly for this design since it is a key-value based database with scalability built in.
Overall, I am okay with after the resource is added, that it takes some time for it to fully propogate to all DB replicas because eventual consistency is OK. However, we want to keep durability (write requests) and latency (making redirect as quickly as possible)
For our caching strategy I will use a write-through caching strategy. This means during our write requests we will confirm the data is saved in both the cache and database before returning the response to the client.
Trade-offs I am opting to use a write-through cache strategy that prioritizes reads over writes. I think this is a fair trade-off given our read-to-write ratio
Another trade-off we are making is around consistency for latency. Since we have chosen db replication to be asynchronous it is possible not all information datapoints will be immediately available to all replicas. However, I think this is a fair trade-off since users may not share or use the link instantly.
Some failure scenarios
Bottlenecks
Instead of using a write-through caching strategy, I can opt in for a write-back strategy where we write to the cache immediately and asynchronously write to the DB. This will vastly improve our write latency, but will introduce complexity in adding an asynchronous process. If the asynchronous process fails, then we will have inconsistent data in both
Additionally, since our system is only eventually consistent, there is a few scenarios where this may not be acceptable. Let's say there is a very famous person who posts a link and within seconds we get 100s of thousands of requests. There are 2 problems here now:
the shortened url hasn't been replicated to all db nodes (especially the ones across the world);
we are getting a thundering herd problem - all of these requests are going to cache miss and all go to the disk which is slow and can cause additional problems/cost in our DB usage.
We can solve this problem by using a "push" based approach in cache for famous/reserve users - we first write in cache and then we write (and replicate) on disk. That would solve the replication/and thundering herd problem, but only if the cache daemon on the application server can have the ability to precisely determine the node id where the cache node with the resource is located.