{"id":29521284,"url":"https://github.com/dangphu2412/system-design-tiny-url","last_synced_at":"2026-05-03T17:31:50.886Z","repository":{"id":293942680,"uuid":"985565854","full_name":"dangphu2412/system-design-tiny-url","owner":"dangphu2412","description":"I develop this repository to have a real hands-on practice on system design and really test my system","archived":false,"fork":false,"pushed_at":"2025-07-23T04:23:31.000Z","size":1248,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-23T06:18:04.833Z","etag":null,"topics":["cassandra","k8s","locust","nestjs","tinyurl"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dangphu2412.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-18T03:32:21.000Z","updated_at":"2025-07-23T04:23:34.000Z","dependencies_parsed_at":"2025-05-18T04:31:52.557Z","dependency_job_id":"f2dafad9-983f-4a33-8804-ab5b6648cb7d","html_url":"https://github.com/dangphu2412/system-design-tiny-url","commit_stats":null,"previous_names":["dangphu2412/system-design-tiny-url"],"tags_count":0,"template":false,"template_full_name":"dangphu2412/posrgres-cdc","purl":"pkg:github/dangphu2412/system-design-tiny-url","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dangphu2412%2Fsystem-design-tiny-url","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dangphu2412%2Fsystem-design-tiny-url/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dangphu2412%2Fsystem-design-tiny-url/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dangphu2412%2Fsystem-design-tiny-url/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dangphu2412","download_url":"https://codeload.github.com/dangphu2412/system-design-tiny-url/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dangphu2412%2Fsystem-design-tiny-url/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32578578,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T06:36:36.687Z","status":"ssl_error","status_checked_at":"2026-05-03T06:36:09.306Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cassandra","k8s","locust","nestjs","tinyurl"],"created_at":"2025-07-16T17:00:45.584Z","updated_at":"2026-05-03T17:31:50.870Z","avatar_url":"https://github.com/dangphu2412.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Tiny Url\n\n## Level: Easy\n## Description: \n\u003e Given a url, design a web API that generates a shorter and unique alias of it\n\nExample\nInput(102 characters):\n\nhttps://phu.com/this-link-is-handsome\n\nOutput(28 characters):\n\nhttps://tinyurl.com/5n6et7uf\n\nThe service will create an alias for the original URL with a shorter length. If you click on the shorter URL it should redirect to the longer URL.\n\n## Functional Requirements\n- Given a url, generate a shorter and unique alias of it\n- When user accesses short link, redirect them to the original url\n\n## Nonfunctional Requirements:\n  - [x] 99.99% Availability\n  - [] 150ms latency on redirection\n  - [] Links expire at 5 years by default\n  - [] Should perform globally\n  - [x] All urls are public\n  - [x] Each url is 2Kb\n  - [x] Cache TTL 24 hrs\n  - [x] Estimated Usage\n  - [x] 100 Reads per Write\n  - [x] 500,000 urls created every month\n## References:\nhttps://www.geeksforgeeks.org/system-design-url-shortening-service/\n\n## Let's break down the problems:\nBased on functional requirements:\n- Given a url, generate a shorter and unique alias of it\n- When user accesses short link, redirect them to the original url\n\nSo, how do we generate the shorter link?\n- Hashing: technique of transformation from 1 input to the same output, no way traverse back, took time due to computing resources.\n  - MD5 or SHA256 generate **256bits** output, its a long string\n- Encoding: technique of transformation from 1 input to the same output, can decode, 1-1 unique generation\n  - Base62: from by a-z, A-Z, 0-9 (26+26+10=62).\n- Counter increment: Eventually increase, no duplication.\n  - Counter of database can reach a maximum size of number:\n    - integer: 4 bytes\n    - bigint: 8 bytes\n\n## ID Generation:\n500,000 urls/month -\u003e 6mil record/year -\u003e 30mil/5year -\u003e 60mil/10year\nSo the shorten id should serve at least 60mil variants for 10 years.\n\nShorten ID length should be 7 characters.\n\n### Auto generation base62 (encoding):\nBase62 generate 62 variants -\u003e 7 characters will have 62 pow 7 = 395.747.437.888 (YES)\n\n### Auto generation base64 (encoding):\nBase62 generate 64 variants -\u003e 7 characters will have 64 pow 7 = 4.398.046.511.104 (YES)\nBut character of + / break URL when routing. (NO)\n\n### Counter using number increment:\nint 4 bytes: 4,294,967,295\nBut we need only 7 characters, so result in 4,967,295 (not even fit for 1 year)\n-\u003e This approach cannot fit (NO)\n\n### SHA256 (Hashing-256bits):\n- Hash based on input will output 256bits length -\u003e 32bytes\n- For full string, it is unique, but we need length of 7 only, so the cut **can be duplicated** (NO)\n\n\u003e Possible solution is Base62 generation\n\n## To ensure the generation not randomly duplicated, we generate:\n\n### 🔐 Short ID Generation Algorithm\n\nDetail implementation [here](https://github.com/dangphu2412/system-design-tiny-url/blob/18f100f4c558ee6171aba6f4c6a50ff998ec641a/tinyurl-server/src/tiny-url/shortid-factory.ts)\n\nThis service creates **7-character base62 IDs** using a mix of time and randomness:\n\n1. **Timestamp-based part**\n\n  * Takes the **last 8 digits** of `Date.now()` → gives \\~27 bits of data.\n  * This adds time-based uniqueness, so IDs are sort of chronological.\n\n2. **Random part**\n\n  * Generates a random number from `0` to `62³` (\\~18 bits).\n  * Ensures that even IDs generated in the same millisecond are still different.\n\n3. **Combine \u0026 Convert**\n\n  * Combines the timestamp and randomness into one big number.\n  * Converts it into **base62** (`0-9a-zA-Z`) → makes it compact.\n  * Pads to 7 characters and slices to keep it clean.\n\n---\n\n### 🧠 Why it works\n\n* Base62 encoding packs more info into fewer characters.\n* Combining time + randomness avoids collisions for most use cases.\n* Always outputs a fixed-length, URL-friendly string.\n\n## Data Capacity Modeling\nFor 5 years:\n30mil\nAverage long URL size is 2Kb for 2048 characters (Max browser URL)\n\n```\n1 character = 1 byte -\u003e 2048 characters = 2Kb\n30.000.000 * 2 = 30.000.000 Kb ~ 29296 Mb ~ 28 Gb\n```\n\n## Database\n\u003e Given a url, generate a shorter and unique alias of it.\n- A Key Value database should be the best fit.\n- Also offer a scalable read database over the write overhead.\n\n## Cache storage\n- 20% of URLs can be stored in a cache\n- 28 Gb * 0.2 = 5.6 Gb\n\n## Job for cleaning data over 5 years\n- Define a scheduled job run per 5 years to clean up least access data.\n- The job to iterate over the database which may causing overhead to the database in the cleaning time. So how do we avoid pressure on the database?\n- Also, we need to invalidate the cached url as well?\n\n## Performance testing\n\n## Scale strategy\n- Application scale\n- Cache server scale\n  - Setup redis cluster\n- Database scale\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdangphu2412%2Fsystem-design-tiny-url","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdangphu2412%2Fsystem-design-tiny-url","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdangphu2412%2Fsystem-design-tiny-url/lists"}