[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-4948":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":22,"archived":23,"fork":23,"defaultBranch":24,"hasWiki":25,"hasPages":23,"topics":26,"createdAt":10,"pushedAt":10,"updatedAt":34,"readmeContent":35,"aiSummary":36,"trendingCount":16,"starSnapshotCount":16,"syncStatus":37,"lastSyncTime":38,"discoverSource":39},4948,"asynq","hibiken\u002Fasynq","hibiken","Simple, reliable, and efficient distributed task queue in Go","",null,"Go",13366,941,83,215,0,7,27,105,34,106.42,"MIT License",false,"master",true,[27,28,29,30,31,32,33],"asynchronous-tasks","background-jobs","go","golang","redis","task-queue","worker-pool","2026-06-12 04:00:24","\u003Cimg src=\"https:\u002F\u002Fuser-images.githubusercontent.com\u002F11155743\u002F114697792-ffbfa580-9d26-11eb-8e5b-33bef69476dc.png\" alt=\"Asynq logo\" width=\"360px\" \u002F>\n\n# Simple, reliable & efficient distributed task queue in Go\n\n[![GoDoc](https:\u002F\u002Fgodoc.org\u002Fgithub.com\u002Fhibiken\u002Fasynq?status.svg)](https:\u002F\u002Fgodoc.org\u002Fgithub.com\u002Fhibiken\u002Fasynq)\n[![Go Report Card](https:\u002F\u002Fgoreportcard.com\u002Fbadge\u002Fgithub.com\u002Fhibiken\u002Fasynq)](https:\u002F\u002Fgoreportcard.com\u002Freport\u002Fgithub.com\u002Fhibiken\u002Fasynq)\n![Build Status](https:\u002F\u002Fgithub.com\u002Fhibiken\u002Fasynq\u002Fworkflows\u002Fbuild\u002Fbadge.svg)\n[![License: MIT](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flicense-MIT-green.svg)](https:\u002F\u002Fopensource.org\u002Flicenses\u002FMIT)\n[![Gitter chat](https:\u002F\u002Fbadges.gitter.im\u002Fgo-asynq\u002Fgitter.svg)](https:\u002F\u002Fgitter.im\u002Fgo-asynq\u002Fcommunity)\n\nAsynq is a Go library for queueing tasks and processing them asynchronously with workers. It's backed by [Redis](https:\u002F\u002Fredis.io\u002F) and is designed to be scalable yet easy to get started.\n\nHighlevel overview of how Asynq works:\n\n- Client puts tasks on a queue\n- Server pulls tasks off queues and starts a worker goroutine for each task\n- Tasks are processed concurrently by multiple workers\n\nTask queues are used as a mechanism to distribute work across multiple machines. A system can consist of multiple worker servers and brokers, giving way to high availability and horizontal scaling.\n\n**Example use case**\n\n![Task Queue Diagram](https:\u002F\u002Fuser-images.githubusercontent.com\u002F11155743\u002F116358505-656f5f80-a806-11eb-9c16-94e49dab0f99.jpg)\n\n## Features\n\n- Guaranteed [at least one execution](https:\u002F\u002Fwww.cloudcomputingpatterns.org\u002Fat_least_once_delivery\u002F) of a task\n- Scheduling of tasks\n- [Retries](https:\u002F\u002Fgithub.com\u002Fhibiken\u002Fasynq\u002Fwiki\u002FTask-Retry) of failed tasks\n- Automatic recovery of tasks in the event of a worker crash\n- [Weighted priority queues](https:\u002F\u002Fgithub.com\u002Fhibiken\u002Fasynq\u002Fwiki\u002FQueue-Priority#weighted-priority)\n- [Strict priority queues](https:\u002F\u002Fgithub.com\u002Fhibiken\u002Fasynq\u002Fwiki\u002FQueue-Priority#strict-priority)\n- Low latency to add a task since writes are fast in Redis\n- De-duplication of tasks using [unique option](https:\u002F\u002Fgithub.com\u002Fhibiken\u002Fasynq\u002Fwiki\u002FUnique-Tasks)\n- Allow [timeout and deadline per task](https:\u002F\u002Fgithub.com\u002Fhibiken\u002Fasynq\u002Fwiki\u002FTask-Timeout-and-Cancelation)\n- Allow [aggregating group of tasks](https:\u002F\u002Fgithub.com\u002Fhibiken\u002Fasynq\u002Fwiki\u002FTask-aggregation) to batch multiple successive operations\n- [Flexible handler interface with support for middlewares](https:\u002F\u002Fgithub.com\u002Fhibiken\u002Fasynq\u002Fwiki\u002FHandler-Deep-Dive)\n- [Ability to pause queue](\u002Ftools\u002Fasynq\u002FREADME.md#pause) to stop processing tasks from the queue\n- [Periodic Tasks](https:\u002F\u002Fgithub.com\u002Fhibiken\u002Fasynq\u002Fwiki\u002FPeriodic-Tasks)\n- [Support Redis Sentinels](https:\u002F\u002Fgithub.com\u002Fhibiken\u002Fasynq\u002Fwiki\u002FAutomatic-Failover) for high availability\n- Integration with [Prometheus](https:\u002F\u002Fprometheus.io\u002F) to collect and visualize queue metrics\n- [Web UI](#web-ui) to inspect and remote-control queues and tasks\n- [CLI](#command-line-tool) to inspect and remote-control queues and tasks\n\n## Stability and Compatibility\n\n**Status**: The library relatively stable and is currently undergoing **moderate development** with less frequent breaking API changes.\n\n> ☝️ **Important Note**: Current major version is zero (`v0.x.x`) to accommodate rapid development and fast iteration while getting early feedback from users (_feedback on APIs are appreciated!_). The public API could change without a major version update before `v1.0.0` release.\n\n### Redis Cluster Compatibility\n\nSome of the lua scripts in this library may not be compatible with Redis Cluster.\n\n## Sponsoring\nIf you are using this package in production, **please consider sponsoring the project to show your support!**\n\n## Quickstart\nMake sure you have Go installed ([download](https:\u002F\u002Fgolang.org\u002Fdl\u002F)). The **last two** Go versions are supported (See https:\u002F\u002Fgo.dev\u002Fdl).\n\nInitialize your project by creating a folder and then running `go mod init github.com\u002Fyour\u002Frepo` ([learn more](https:\u002F\u002Fblog.golang.org\u002Fusing-go-modules)) inside the folder. Then install Asynq library with the [`go get`](https:\u002F\u002Fgolang.org\u002Fcmd\u002Fgo\u002F#hdr-Add_dependencies_to_current_module_and_install_them) command:\n\n```sh\ngo get -u github.com\u002Fhibiken\u002Fasynq\n```\n\nMake sure you're running a Redis server locally or from a [Docker](https:\u002F\u002Fhub.docker.com\u002F_\u002Fredis) container. Version `4.0` or higher is required.\n\nNext, write a package that encapsulates task creation and task handling.\n\n```go\npackage tasks\n\nimport (\n    \"context\"\n    \"encoding\u002Fjson\"\n    \"fmt\"\n    \"log\"\n    \"time\"\n    \"github.com\u002Fhibiken\u002Fasynq\"\n)\n\n\u002F\u002F A list of task types.\nconst (\n    TypeEmailDelivery   = \"email:deliver\"\n    TypeImageResize     = \"image:resize\"\n)\n\ntype EmailDeliveryPayload struct {\n    UserID     int\n    TemplateID string\n}\n\ntype ImageResizePayload struct {\n    SourceURL string\n}\n\n\u002F\u002F----------------------------------------------\n\u002F\u002F Write a function NewXXXTask to create a task.\n\u002F\u002F A task consists of a type and a payload.\n\u002F\u002F----------------------------------------------\n\nfunc NewEmailDeliveryTask(userID int, tmplID string) (*asynq.Task, error) {\n    payload, err := json.Marshal(EmailDeliveryPayload{UserID: userID, TemplateID: tmplID})\n    if err != nil {\n        return nil, err\n    }\n    return asynq.NewTask(TypeEmailDelivery, payload), nil\n}\n\nfunc NewImageResizeTask(src string) (*asynq.Task, error) {\n    payload, err := json.Marshal(ImageResizePayload{SourceURL: src})\n    if err != nil {\n        return nil, err\n    }\n    \u002F\u002F task options can be passed to NewTask, which can be overridden at enqueue time.\n    return asynq.NewTask(TypeImageResize, payload, asynq.MaxRetry(5), asynq.Timeout(20 * time.Minute)), nil\n}\n\n\u002F\u002F---------------------------------------------------------------\n\u002F\u002F Write a function HandleXXXTask to handle the input task.\n\u002F\u002F Note that it satisfies the asynq.HandlerFunc interface.\n\u002F\u002F\n\u002F\u002F Handler doesn't need to be a function. You can define a type\n\u002F\u002F that satisfies asynq.Handler interface. See examples below.\n\u002F\u002F---------------------------------------------------------------\n\nfunc HandleEmailDeliveryTask(ctx context.Context, t *asynq.Task) error {\n    var p EmailDeliveryPayload\n    if err := json.Unmarshal(t.Payload(), &p); err != nil {\n        return fmt.Errorf(\"json.Unmarshal failed: %v: %w\", err, asynq.SkipRetry)\n    }\n    log.Printf(\"Sending Email to User: user_id=%d, template_id=%s\", p.UserID, p.TemplateID)\n    \u002F\u002F Email delivery code ...\n    return nil\n}\n\n\u002F\u002F ImageProcessor implements asynq.Handler interface.\ntype ImageProcessor struct {\n    \u002F\u002F ... fields for struct\n}\n\nfunc (processor *ImageProcessor) ProcessTask(ctx context.Context, t *asynq.Task) error {\n    var p ImageResizePayload\n    if err := json.Unmarshal(t.Payload(), &p); err != nil {\n        return fmt.Errorf(\"json.Unmarshal failed: %v: %w\", err, asynq.SkipRetry)\n    }\n    log.Printf(\"Resizing image: src=%s\", p.SourceURL)\n    \u002F\u002F Image resizing code ...\n    return nil\n}\n\nfunc NewImageProcessor() *ImageProcessor {\n\treturn &ImageProcessor{}\n}\n```\n\nIn your application code, import the above package and use [`Client`](https:\u002F\u002Fpkg.go.dev\u002Fgithub.com\u002Fhibiken\u002Fasynq?tab=doc#Client) to put tasks on queues.\n\n```go\npackage main\n\nimport (\n    \"log\"\n    \"time\"\n\n    \"github.com\u002Fhibiken\u002Fasynq\"\n    \"your\u002Fapp\u002Fpackage\u002Ftasks\"\n)\n\nconst redisAddr = \"127.0.0.1:6379\"\n\nfunc main() {\n    client := asynq.NewClient(asynq.RedisClientOpt{Addr: redisAddr})\n    defer client.Close()\n\n    \u002F\u002F ------------------------------------------------------\n    \u002F\u002F Example 1: Enqueue task to be processed immediately.\n    \u002F\u002F            Use (*Client).Enqueue method.\n    \u002F\u002F ------------------------------------------------------\n\n    task, err := tasks.NewEmailDeliveryTask(42, \"some:template:id\")\n    if err != nil {\n        log.Fatalf(\"could not create task: %v\", err)\n    }\n    info, err := client.Enqueue(task)\n    if err != nil {\n        log.Fatalf(\"could not enqueue task: %v\", err)\n    }\n    log.Printf(\"enqueued task: id=%s queue=%s\", info.ID, info.Queue)\n\n\n    \u002F\u002F ------------------------------------------------------------\n    \u002F\u002F Example 2: Schedule task to be processed in the future.\n    \u002F\u002F            Use ProcessIn or ProcessAt option.\n    \u002F\u002F ------------------------------------------------------------\n\n    info, err = client.Enqueue(task, asynq.ProcessIn(24*time.Hour))\n    if err != nil {\n        log.Fatalf(\"could not schedule task: %v\", err)\n    }\n    log.Printf(\"enqueued task: id=%s queue=%s\", info.ID, info.Queue)\n\n\n    \u002F\u002F ----------------------------------------------------------------------------\n    \u002F\u002F Example 3: Set other options to tune task processing behavior.\n    \u002F\u002F            Options include MaxRetry, Queue, Timeout, Deadline, Unique etc.\n    \u002F\u002F ----------------------------------------------------------------------------\n\n    task, err = tasks.NewImageResizeTask(\"https:\u002F\u002Fexample.com\u002Fmyassets\u002Fimage.jpg\")\n    if err != nil {\n        log.Fatalf(\"could not create task: %v\", err)\n    }\n    info, err = client.Enqueue(task, asynq.MaxRetry(10), asynq.Timeout(3 * time.Minute))\n    if err != nil {\n        log.Fatalf(\"could not enqueue task: %v\", err)\n    }\n    log.Printf(\"enqueued task: id=%s queue=%s\", info.ID, info.Queue)\n}\n```\n\nNext, start a worker server to process these tasks in the background. To start the background workers, use [`Server`](https:\u002F\u002Fpkg.go.dev\u002Fgithub.com\u002Fhibiken\u002Fasynq?tab=doc#Server) and provide your [`Handler`](https:\u002F\u002Fpkg.go.dev\u002Fgithub.com\u002Fhibiken\u002Fasynq?tab=doc#Handler) to process the tasks.\n\nYou can optionally use [`ServeMux`](https:\u002F\u002Fpkg.go.dev\u002Fgithub.com\u002Fhibiken\u002Fasynq?tab=doc#ServeMux) to create a handler, just as you would with [`net\u002Fhttp`](https:\u002F\u002Fgolang.org\u002Fpkg\u002Fnet\u002Fhttp\u002F) Handler.\n\n```go\npackage main\n\nimport (\n    \"log\"\n\n    \"github.com\u002Fhibiken\u002Fasynq\"\n    \"your\u002Fapp\u002Fpackage\u002Ftasks\"\n)\n\nconst redisAddr = \"127.0.0.1:6379\"\n\nfunc main() {\n    srv := asynq.NewServer(\n        asynq.RedisClientOpt{Addr: redisAddr},\n        asynq.Config{\n            \u002F\u002F Specify how many concurrent workers to use\n            Concurrency: 10,\n            \u002F\u002F Optionally specify multiple queues with different priority.\n            Queues: map[string]int{\n                \"critical\": 6,\n                \"default\":  3,\n                \"low\":      1,\n            },\n            \u002F\u002F See the godoc for other configuration options\n        },\n    )\n\n    \u002F\u002F mux maps a type to a handler\n    mux := asynq.NewServeMux()\n    mux.HandleFunc(tasks.TypeEmailDelivery, tasks.HandleEmailDeliveryTask)\n    mux.Handle(tasks.TypeImageResize, tasks.NewImageProcessor())\n    \u002F\u002F ...register other handlers...\n\n    if err := srv.Run(mux); err != nil {\n        log.Fatalf(\"could not run server: %v\", err)\n    }\n}\n```\n\nFor a more detailed walk-through of the library, see our [Getting Started](https:\u002F\u002Fgithub.com\u002Fhibiken\u002Fasynq\u002Fwiki\u002FGetting-Started) guide.\n\nTo learn more about `asynq` features and APIs, see the package [godoc](https:\u002F\u002Fgodoc.org\u002Fgithub.com\u002Fhibiken\u002Fasynq).\n\n## Web UI\n\n[Asynqmon](https:\u002F\u002Fgithub.com\u002Fhibiken\u002Fasynqmon) is a web based tool for monitoring and administrating Asynq queues and tasks.\n\nHere's a few screenshots of the Web UI:\n\n**Queues view**\n\n![Web UI Queues View](https:\u002F\u002Fuser-images.githubusercontent.com\u002F11155743\u002F114697016-07327f00-9d26-11eb-808c-0ac841dc888e.png)\n\n**Tasks view**\n\n![Web UI TasksView](https:\u002F\u002Fuser-images.githubusercontent.com\u002F11155743\u002F114697070-1f0a0300-9d26-11eb-855c-d3ec263865b7.png)\n\n**Metrics view**\n\u003Cimg width=\"1532\" alt=\"Screen Shot 2021-12-19 at 4 37 19 PM\" src=\"https:\u002F\u002Fuser-images.githubusercontent.com\u002F10953044\u002F146777420-cae6c476-bac6-469c-acce-b2f6584e8707.png\">\n\n**Settings and adaptive dark mode**\n\n![Web UI Settings and adaptive dark mode](https:\u002F\u002Fuser-images.githubusercontent.com\u002F11155743\u002F114697149-3517c380-9d26-11eb-9f7a-ae2dd00aad5b.png)\n\nFor details on how to use the tool, refer to the tool's [README](https:\u002F\u002Fgithub.com\u002Fhibiken\u002Fasynqmon#readme).\n\n## Command Line Tool\n\nAsynq ships with a command line tool to inspect the state of queues and tasks.\n\nTo install the CLI tool, run the following command:\n\n```sh\ngo install github.com\u002Fhibiken\u002Fasynq\u002Ftools\u002Fasynq@latest\n```\n\nHere's an example of running the `asynq dash` command:\n\n![Gif](\u002Fdocs\u002Fassets\u002Fdash.gif)\n\nFor details on how to use the tool, refer to the tool's [README](\u002Ftools\u002Fasynq\u002FREADME.md).\n\n## Contributing\n\nWe are open to, and grateful for, any contributions (GitHub issues\u002FPRs, feedback on [Gitter channel](https:\u002F\u002Fgitter.im\u002Fgo-asynq\u002Fcommunity), etc) made by the community.\n\nPlease see the [Contribution Guide](\u002FCONTRIBUTING.md) before contributing.\n\n## License\n\nCopyright (c) 2019-present [Ken Hibino](https:\u002F\u002Fgithub.com\u002Fhibiken) and [Contributors](https:\u002F\u002Fgithub.com\u002Fhibiken\u002Fasynq\u002Fgraphs\u002Fcontributors). `Asynq` is free and open-source software licensed under the [MIT License](https:\u002F\u002Fgithub.com\u002Fhibiken\u002Fasynq\u002Fblob\u002Fmaster\u002FLICENSE). Official logo was created by [Vic Shóstak](https:\u002F\u002Fgithub.com\u002Fkoddr) and distributed under [Creative Commons](https:\u002F\u002Fcreativecommons.org\u002Fpublicdomain\u002Fzero\u002F1.0\u002F) license (CC0 1.0 Universal).\n","Asynq 是一个用 Go 语言编写的简单、可靠且高效的分布式任务队列库。它基于 Redis 实现，提供了诸如任务调度、失败重试、自动恢复等核心功能，并支持加权优先级队列和严格优先级队列以满足不同场景下的需求。此外，Asynq 还具备任务去重、超时设置、任务聚合等功能，以及与 Prometheus 集成用于监控和 Web UI\u002FCLI 工具来远程管理和调试任务队列。该工具非常适合需要异步处理后台任务的场景，如邮件发送、图片处理或数据同步等，能够帮助开发者轻松实现系统的高可用性和水平扩展。",2,"2026-06-11 03:01:40","top_language"]