{"id":19677371,"url":"https://github.com/poimen/url-short-rs","last_synced_at":"2025-06-15T04:08:31.262Z","repository":{"id":221714739,"uuid":"755176894","full_name":"Poimen/url-short-rs","owner":"Poimen","description":"A Rust-based url shortener using redis as a backend","archived":false,"fork":false,"pushed_at":"2024-04-11T10:32:30.000Z","size":52,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-27T05:52:59.173Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Poimen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2024-02-09T15:31:00.000Z","updated_at":"2024-03-15T11:37:14.000Z","dependencies_parsed_at":"2024-02-09T16:54:17.034Z","dependency_job_id":"d4613d0f-f511-4258-a70b-9a649fc0934f","html_url":"https://github.com/Poimen/url-short-rs","commit_stats":null,"previous_names":["poimen/playful-panda","poimen/url-short-rs"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Poimen/url-short-rs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Poimen%2Furl-short-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Poimen%2Furl-short-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Poimen%2Furl-short-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Poimen%2Furl-short-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Poimen","download_url":"https://codeload.github.com/Poimen/url-short-rs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Poimen%2Furl-short-rs/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259919461,"owners_count":22932073,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-11-11T17:33:50.060Z","updated_at":"2025-06-15T04:08:31.243Z","avatar_url":"https://github.com/Poimen.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# url-short-rs\n\nThis is a playful repo for playing with code in rust.\n\nIt is an idea for a url shortener that presents a simple API with a Redis backend as a datastore. This would require Redis to have a persistent layer, but as short urls are read more than written, caching this in Redis make for quicker lookups.\n\n## Details\n\nThe backend of Redis is run through docker. There is a docker-compose [file](./docker/docker-compose.yml) that will spin up a Redis instance.\n\nNaturally, using docker-compose for anything outside testing, should be avoided. Please run Redis in a proper cluster/permissions etc.\n\nThe url handler doesn't dedup any data, so you can generate short urls for the same url multiple times, each time will give a different short code. They are all stored separately as well. The url can be set to have a TTL (time-to-live) where it will no longer be available.\n\n## Running\n\nThe project can be run by using the command, in the root:\n```bash\ncargo run\n```\n\nThere is a `.env.development` that sets up the `REDIS_SERVER` url. Please update that to give the proper URL for the redis server.\n\nThis will expect that there is a REDIS server running at the URL. For a test environment, the docker-compose will wil run Redis in a way all the default configuration setup will expect.\n\nThere are some environment variables that can be used:\n\n| Variable         | Description                                       | Default            |\n| ---------------- | --------------------------------------------------| ------------------ |\n| REDIS_SERVER_URL | URL to the REDIS server to use                    | None, Required     |\n| HOST_IP          | Host IP to run the webserver on                   | localhost          |\n| HOST_PORT        | Host Port to run the webserver on                 | 8000               |\n| ALPHABET         | Alphabet to use for short-code generation         | All safe URL codes |\n| SHORT_ID_LENGTH  | Length on short code                              | 7                  |\n| SHORT_ID_REPEAT_CLASH_LENGTH | Number of Repeats to perform if there is a key clash | 5  |\n| REQUEST_TIMEOUT_MS | Request timeout in milliseconds | 300 |\n\nThe Redis server url can contain all the Redis permission/user login details as required. See Redis documentation for details.\n\n\n## Testing\n\nThere is a http [file](./http/test_command.http) that will run test requests against the server.\n\nThe endpoints exposed are:\n```\nGET /api/health\n```\nCheck if the service is up and running\n\n```\nPOST /api/short-code\n```\nGenerate a shortcode for a given url\n\n```\nGET /{short-code}\n```\nRedirect to the short code, or 404\n\n```\nGET /metrics\n```\nPrometheus metrics\n\n## Web client\n\nThe initial version was written using actix-web, and then ported to axum. Axum performed better, from with random benchmarks.\n\nThe axum version has since been iterated upon and improved.\n\n## Performance using bombardier\n\nWrite performance (actix-web):\n```\n$ bombardier -c 125 -n 100000 -m POST http://127.0.0.1:8000/api/short-code -H \"Content-Type: application/json\" -b '{\"ShortUrl\": \"http://localhost\", \"Seconds\": 100}'\nBombarding http://127.0.0.1:8000/api/short-code with 100000 request(s) using 125 connection(s)\n 100000 / 100000 [==================================================================================] 100.00% 11327/s 8s\nDone!\nStatistics        Avg      Stdev        Max\n  Reqs/sec     11590.25    2265.67   23626.36\n  Latency       10.78ms     1.21ms    32.66ms\n  HTTP codes:\n    1xx - 0, 2xx - 100000, 3xx - 0, 4xx - 0, 5xx - 0\n    others - 0\n  Throughput:     3.40MB/s\n```\n\nWrite performance (axum):\n```\n$ bombardier -c 125 -n 100000 -m POST http://127.0.0.1:8000/api/short-code -H \"Content-Type: application/json\" -b '{\"ShortUrl\": \"http://localhost\", \"Seconds\": 100}'\nBombarding http://127.0.0.1:8000/api/short-code with 100000 request(s) using 125 connection(s)\n 100000 / 100000 [==================================================================================] 100.00% 41529/s 2s\nDone!\nStatistics        Avg      Stdev        Max\n  Reqs/sec     44817.37    8597.59   62631.09\n  Latency        2.79ms   505.56us    15.79ms\n  HTTP codes:\n    1xx - 0, 2xx - 100000, 3xx - 0, 4xx - 0, 5xx - 0\n    others - 0\n  Throughput:    13.12MB/s\n```\n\nRedirect performance (actix-web):\n```\n$ bombardier -c 125 -n 100000 -m GET http://localhost:8000/FzZeTeK\nBombarding http://localhost:8000/FzZeTeK with 100000 request(s) using 125 connection(s)\n 100000 / 100000 [==================================================================================] 100.00% 83040/s 1s\nDone!\nStatistics        Avg      Stdev        Max\n  Reqs/sec     96462.98   18407.90  126084.82\n  Latency        1.29ms   467.18us    19.38ms\n  HTTP codes:\n    1xx - 0, 2xx - 0, 3xx - 100000, 4xx - 0, 5xx - 0\n    others - 0\n  Throughput:    17.27MB/s\n```\n\nRedirect performance (axum):\n```\n$ bombardier -c 125 -n 100000 -m GET http://localhost:8000/FzZeTeK\nBombarding http://localhost:8000/FzZeTeK with 100000 request(s) using 125 connection(s)\n 100000 / 100000 [==================================================================================] 100.00% 83014/s 1s\nDone!\nStatistics        Avg      Stdev        Max\n  Reqs/sec     91774.95   20325.00  124183.63\n  Latency        1.36ms   620.62us    25.01ms\n  HTTP codes:\n    1xx - 0, 2xx - 0, 3xx - 100000, 4xx - 0, 5xx - 0\n    others - 0\n  Throughput:    24.96MB/s\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpoimen%2Furl-short-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpoimen%2Furl-short-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpoimen%2Furl-short-rs/lists"}