ZEXD is a URL shortening service designed for speed along with reliability, scalability, and monitoring in mind. This project uses a Go-based backend, with PostgreSQL as the database, DragonflyDB for caching, and integrated monitoring via Prometheus and Grafana.
- URL shortening and redirection having a average response time of 2ms for creation and 1ms for redirection.
- Click tracking and analytics for shortened URLs
- URL expiration management (default: 24 hours)
- Health monitoring with Prometheus and Grafana dashboards
- API documentation via Swagger UI
The performance of ZEXD was tested using the k6 load testing tool. The tests were run on a Lenovo Ideapad Flex 5 with an 11th Gen Intel Core i7 processor and 16GB of RAM.
-
Tests for Url Creation
- Test 1
- 1 VU for 30 seconds
- 16519 requests
- Avg. response time: 1.71ms
- Test 2
- 100 VU for 2 minutes
- 253477 requests
- Avg. response time: 47.19ms
- Test 3
- 200 VU for 2 minutes
- 330481 requests
- Avg. response time: 72.48ms
- Test 4
- 1000 VU for 2 minutes
- 324233 requests
- Avg. response time: 369.2ms
- Test 1
-
Tests for Url Redirection
- Test 1
- 1 VU for 30 seconds
- 25053 requests
- Avg. response time: 1.09ms
- Test 2
- 100 VU for 2 minutes
- 170563 requests
- Avg. response time: 12.39ms
- Test 3
- The server was not able to handle the load of 200 VUs for 2 mins.
- Test 1
See the benchmark results for the performance of ZexD.
Make sure you have the following installed:
- Docker and Docker Compose
- Go 1.23 or later (optional, if you wish to run or develop outside Docker)
git clone https://github.com/AvaterClasher/zexd-backend.git
cd zexd-backend
Create an .env
file in the root directory based on the .env.example
provided:
Change with whatever DB or redis service you are using if not using docker compose.
DB_HOST=postgres
DB_PORT=5432
DB_USER=zexd
DB_PASSWORD=zexd
DB_NAME=zexd_db
DB_SSL=disable
TABLE_NAME=shortened_url # dont change this
EXPIRY_TIME=1440 # Expiration time in minutes
REDIS_DOMAIN=redis://user@dragonflydb:6379/
SERVER_DOMAIN=http://localhost:8080/
This setup is for local development and testing. Any changes made to the code will be reflected here. The environment variables are already set in the docker compose file. To start the service in a local development environment, use:
docker-compose -f compose.local.yml up --build
This uses a pre-built image from Docker Hub. This setup is for production use. The environment variables are already set in the docker compose file. For a production-ready setup:
docker-compose -f compose.prod.yml up -d --build
This setup configures all services (backend, PostgreSQL, DragonflyDB, Prometheus, and Grafana) with production-level configurations.
If you want to run the services independently, here are some examples:
docker run -p 8080:8080 --env-file .env avaterclasher/zexd-backend:v1
- Production: Hosted Swagger documentation is available at https://zexd.onrender.com/swagger/index.html
- Local: Once the service is running locally, access Swagger documentation at http://localhost:8080/swagger/index.html.
This project uses Prometheus and Grafana for monitoring. When started, these services will be available at:
- Prometheus: http://localhost:9090
- Grafana: http://localhost:3000
To log into Grafana, use:
- Username:
admin
- Password:
admin
You can find the Grafana dashboard JSON file in grafana_dashboard.json
for pre-configured metrics related to this project.
The Dockerfile is a multi-stage build with two stages:
- Builder: Builds the Go application.
- Alpine: Copies the compiled application and runs it on a minimal Alpine image for lightweight production usage.
To build and run the image manually:
docker build -t zexd-backend .
docker run -p 8080:8080 --env-file .env zexd-backend
The API endpoints are as follows:
Method | Endpoint | Body | Description |
---|---|---|---|
POST | /api/create | {"url": "https://www.youtube.com", "user_id": "user1"} | Generates a shortened URL |
POST | /api/delete | {"url": "https://www.youtube.com"} | Deletes the shortened URL |
GET | /api/list/{user_id} | Returns the urls of the user | |
GET | /{shortened_url} | Redirects to the original URL | |
GET | /health | Returns the health status of the server |
Contributions are welcome! Please open an issue or submit a pull request if you have any suggestions or improvements.
- Github: Avater Clasher
- Linkedin: Soumyadip Moni
This project is licensed under the MIT License.