{"id":19167717,"url":"https://github.com/nnnlik/url-shorter","last_synced_at":"2026-06-23T14:31:29.956Z","repository":{"id":328526879,"uuid":"1115870725","full_name":"nnnLik/url-shorter","owner":"nnnLik","description":"High-performance URL shortener on FastAPI with asynchronous click processing and code pre-generation","archived":false,"fork":false,"pushed_at":"2025-12-13T19:17:34.000Z","size":100,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-12-15T12:45:09.452Z","etag":null,"topics":["async","docker-compose","dockerslim","fastapi","postgres","rabbitmq","redis","taskiq","url-shortener"],"latest_commit_sha":null,"homepage":"","language":"Python","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/nnnLik.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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-13T18:11:22.000Z","updated_at":"2025-12-13T19:17:38.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/nnnLik/url-shorter","commit_stats":null,"previous_names":["nnnlik/url-shorter"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/nnnLik/url-shorter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nnnLik%2Furl-shorter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nnnLik%2Furl-shorter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nnnLik%2Furl-shorter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nnnLik%2Furl-shorter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nnnLik","download_url":"https://codeload.github.com/nnnLik/url-shorter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nnnLik%2Furl-shorter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34694778,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-23T02:00:07.161Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["async","docker-compose","dockerslim","fastapi","postgres","rabbitmq","redis","taskiq","url-shortener"],"created_at":"2024-11-09T09:38:57.545Z","updated_at":"2026-06-23T14:31:29.951Z","avatar_url":"https://github.com/nnnLik.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# URL Shortener\n\nA link shortening service.\n\n## What It Is\n\nKey features:\n- Redirects are fast (Redis cache, async processing)\n- Click statistics (total clicks, last click time)\n- Top 5 most popular links\n- Codes are pre-generated, so creating a link takes microseconds\n\n## How to Run\n\n```bash\nmake start\n```\n\nThe service will start at `http://localhost:9898`. API documentation will be available at `/docs` (standard FastAPI Swagger).\n\n## What's Inside\n\n- **FastAPI** — main framework\n- **PostgreSQL** — stores links and statistics\n- **Redis** — cache for fast redirects + pool of pre-generated codes\n- **RabbitMQ** — queue for click processing (so redirects aren’t blocked)\n- **TaskIQ** — background tasks (refilling code pool, batch processing clicks)\n\nAll details are in `/docs` after launch.\n\n## How It Works\n\n1. You create a link → get an 8-character code\n2. Someone clicks → instant redirect (from cache), click is logged to queue\n3. Background task collects clicks in batches and updates statistics\n4. Codes are pre-generated in a pool, so you don’t wait during creation\n\n## Useful Commands\n\n- `make up` — start\n- `make down` — stop\n- `make logs` — view logs\n- `make migrate` — run migrations\n- `make shell` — open IPython shell\n\n## Notes\n\n- Code pool refills automatically (when less than 10% remains)\n- Clicks are processed in batches every minute\n- Link cache lives for 24 hours\n- If the code pool is empty — codes are generated synchronously (but this is rare)\n\n## Docker Image Optimization\n\nThis project uses [DockerSlim](https://github.com/slimtoolkit/slim) to minimize image size.\n\n**Image sizes:**\n- Original image: ~667 MB\n- Minified image: ~352 MB (1.9x smaller)\n\n**Automatic minification:**\n\n1. **Auto on start (recommended):**\n   ```bash\n   make start-slim    # checks if minification is needed and runs it automatically\n   ```\n\n2. **Using an environment variable:**\n   ```bash\n   SLIM_BUILD=true make build    # automatically minifies during build\n   ```\n\n3. **Manually:**\n   ```bash\n   make slim-build    # minify the image\n   make slim-start    # minify and run with slim image\n   make auto-slim     # smart minification (only if needed)\n   ```\n\n**Note:** DockerSlim works only locally. In CI/CD, dev images are not minified.\n\n\n**How it works:**\n- `auto-slim` checks hash of `Dockerfile` and `pyproject.toml` — only minifies if they changed\n- `start-slim` automatically minifies and starts with slim image\n- Volumes (`./src:/opt/app`) still work for hot-reload\n\n## TODO\n\n- [ ] Delete expired URLs (cleanup task for expired links)\n- [ ] Store clicks in ClickHouse with metadata (IP, user-agent, timestamp, etc.)\n- [ ] Investigate RPS limits and optimize performance\n- [x] Optimize Docker image size (DockerSlim)\n- [ ] QR code generation for links\n- [x] CI/CD pipeline setup (GitHub Actions)\n- [ ] Add tests (unit + integration)\n- [ ] User authentication, rate limits per user, personal links\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnnnlik%2Furl-shorter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnnnlik%2Furl-shorter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnnnlik%2Furl-shorter/lists"}