package lwt

  1. Overview
  2. Docs
Promises and event-driven I/O

Install

dune-project
 Dependency

Authors

Maintainers

Sources

6.1.0.tar.gz
md5=16d58c8295b5273e58779db0ad1f967a
sha512=d5eafe2f5d2dc576b76db15b84caf69d673cb3d736dc3e40b239e6a42c6036658c78bd4b883e9f2b9f627c144be515b1824f1f2de9d79c05d5744c456fb63257

Description

A promise is a value that may become determined in the future.

Lwt provides typed, composable promises. Promises that are resolved by I/O are resolved by Lwt in parallel.

Meanwhile, OCaml code, including code creating and waiting on promises, runs in a single thread by default. This reduces the need for locks or other synchronization primitives. Code can be run in parallel on an opt-in basis.

Published: 03 Feb 2026

README

Lwt

version GitHub Actions status

Lwt is a concurrent programming library for OCaml. It provides a single data type: the promise, which is a value that will become resolved in the future. Creating a promise spawns a computation. When that computation is I/O, Lwt runs it in parallel with your OCaml code.

OCaml code, including creating and waiting on promises, is run in a single thread by default, so you don't have to worry about locking or preemption. You can detach code to be run in separate threads on an opt-in basis.

Here is a simplistic Lwt program which requests the Google front page, and fails if the request is not completed in five seconds:

let () =
  let request =
    let%lwt addresses = Lwt_unix.getaddrinfo "google.com" "80" [] in
    let google = Lwt_unix.((List.hd addresses).ai_addr) in

    Lwt_io.(with_connection google (fun (incoming, outgoing) ->
      write outgoing "GET / HTTP/1.1\r\n";%lwt
      write outgoing "Connection: close\r\n\r\n";%lwt
      let%lwt response = read incoming in
      Lwt.return (Some response)))
  in

  let timeout =
    Lwt_unix.sleep 5.;%lwt
    Lwt.return_none
  in

  match Lwt_main.run (Lwt.pick [request; timeout]) with
  | Some response -> print_string response
  | None -> prerr_endline "Request timed out"; exit 1

(* ocamlfind opt -package lwt.unix,lwt_ppx -linkpkg example.ml && ./a.out *)

If you are not using the lwt_ppx syntax extension, you can use the let* binding opoerators from the Lwt.Syntax module instead.

let () =
  let open Lwt.Syntax in
  let request =
    let* addresses = Lwt_unix.getaddrinfo "google.com" "80" [] in
    let google = Lwt_unix.((List.hd addresses).ai_addr) in

    Lwt_io.(with_connection google (fun (incoming, outgoing) ->
      let* () = write outgoing "GET / HTTP/1.1\r\n" in
      let* () = write outgoing "Connection: close\r\n\r\n" in
      let* response = read incoming in
      Lwt.return (Some response)))
  in

  let timeout =
    let* () = Lwt_unix.sleep 5. in
    Lwt.return_none
  in

  match Lwt_main.run (Lwt.pick [request; timeout]) with
  | Some response -> print_string response
  | None -> prerr_endline "Request timed out"; exit 1

(* ocamlfind opt -package lwt.unix,lwt_ppx -linkpkg example.ml && ./a.out *)

In the program above, functions such as Lwt_io.write create promises. The let%lwt ... in construct (provided by lwt_ppx) or the let* ... in construct (provided by Lwt.Syntax) are used to wait for a promise to resolve. The code after in is scheduled to run after the code inside the let...in has resolved.

Lwt.pick races promises against each other, and behaves as the first one to complete.

Lwt_main.run forces the whole promise-computation network to be executed. All the visible OCaml code is run in a single thread, but Lwt internally uses a combination of worker threads and non-blocking file descriptors to resolve in parallel the promises that do I/O.


Overview

Lwt compiles to native code on Linux, macOS, Windows, and other systems. It's also routinely compiled to JavaScript for the front end and Node by js_of_ocaml.

In Lwt,

  • The core library Lwt provides promises...
  • ...and a few pure-OCaml helpers, such as promise-friendly mutexes, condition variables, and mvars.
  • There is a big Unix binding, Lwt_unix that binds almost every Unix system call. A higher-level module Lwt_io provides nice I/O channels.
  • Lwt_process is for subprocess handling.
  • Lwt_preemptive spawns system threads.
  • The PPX syntax allows using all of the above without going crazy!
  • There are also some other helpers, such as Lwt_react for reactive programming. See the table of contents on the linked manual pages!

Installing

  1. Use your system package manager to install a development libev package. It is often called libev-dev or libev-devel.
  2. opam install conf-libev lwt

Documentation

We are currently working on improving the Lwt documentation (drastically; we are rewriting the manual). In the meantime:

  • The current manual can be found here.
  • Mirage has a nicely-written Lwt tutorial.
  • An example of a simple server written in Lwt.
  • Concurrent Programming with Lwt is a nice source of Lwt examples. They are translations of code from the excellent Real World OCaml, but are just as useful if you are not reading the book.

Note: much of the current manual refers to 'a Lwt.t as "lightweight threads" or just "threads." This will be fixed in the new manual. 'a Lwt.t is a promise, and has nothing to do with system or preemptive threads.


Contact

Open an issue, visit Discord chat, ask on discuss.ocaml.org, or on Stack Overflow.

Release announcements are made on discuss.ocaml.org. Watching the repo for "Releases only" is also an option.


Contributing

  • CONTRIBUTING.md contains tips for working on the code, such as how to check the code out, how review works, etc. There is also a high-level outline of the code base.
  • Ask us anything, whether it's about working on Lwt, or any question at all about it :)
  • The documentation always needs proofreading and fixes.
  • You are welcome to pick up any other issue, review a PR, add your opinion, etc.
  • Any feedback is welcome, including how to make contributing easier!

Libraries to use with Lwt

Dependencies (5)

  1. ocplib-endian
  2. dune-configurator
  3. cppo build & >= "1.1"
  4. ocaml >= "4.14"
  5. dune >= "3.18"

Dev Dependencies (2)

  1. odoc with-doc & >= "2.3"
  2. ocamlfind dev & >= "1.7.3-1"

  1. 0install >= "2.15.1"
  2. aches-lwt
  3. activitypub
  4. albatross
  5. alcotest-lwt
  6. alcotest-mirage
  7. ambient-context-lwt
  8. amqp-client >= "1.1.0"
  9. amqp-client-lwt
  10. angstrom-lwt-unix >= "0.11.0"
  11. anthill
  12. anycache-lwt
  13. archi-lwt
  14. arp
  15. awa-mirage
  16. aws-lwt
  17. aws-s3-lwt < "4.4.0" | >= "4.8.1"
  18. awsm-lwt
  19. azure-cosmos-db
  20. balancer
  21. bastet_lwt
  22. bistro
  23. brisk-reconciler
  24. brozip
  25. builder
  26. builder-web
  27. bun >= "0.3.3"
  28. cachet-lwt
  29. calculon
  30. caldav
  31. camltc
  32. canary
  33. capnp-rpc-lwt < "2.0"
  34. capnp-rpc-unix < "2.1"
  35. caqti-mirage
  36. carton < "1.0.0"
  37. carton-git
  38. carton-lwt
  39. catala-format >= "0.2.0"
  40. cf-lwt
  41. chamelon
  42. chamelon-unix
  43. chamo
  44. charrua-client
  45. charrua-unix
  46. chess_com_api
  47. clz
  48. cmdtui-lambda-term
  49. coap
  50. coap-server-lwt
  51. cohttp-curl-lwt
  52. cohttp-lwt
  53. cohttp-lwt-jsoo
  54. cohttp-lwt-unix
  55. cohttp-mirage
  56. cohttp-server-lwt-unix
  57. comby
  58. comby-semantic
  59. conan-lwt
  60. conduit-lwt
  61. conduit-lwt-unix
  62. cowabloga
  63. crunch
  64. cstruct-lwt
  65. csv-lwt
  66. ctypes >= "0.15.0" & < "0.21.1"
  67. ctypes-foreign >= "0.21.1"
  68. curl_lwt
  69. current
  70. current-albatross-deployer
  71. current_docker
  72. current_examples
  73. current_git
  74. current_github
  75. current_gitlab
  76. current_ocluster
  77. current_rpc
  78. current_slack
  79. current_web
  80. dap
  81. data-encoding < "0.1.1"
  82. devkit >= "1.2"
  83. distributed-lwt
  84. dkim-bin < "0.8.0"
  85. dkim-lwt-unix
  86. dkim-mirage
  87. dlm
  88. dmarc
  89. dns-certify
  90. dns-cli
  91. dns-client < "7.0.3"
  92. dns-client-lwt
  93. dns-client-mirage
  94. dns-forward
  95. dns-forward-lwt-unix
  96. dns-lwt
  97. dns-mirage
  98. dns-resolver
  99. dns-server
  100. dns-stub
  101. dnssd
  102. docker_hub
  103. docteur >= "0.0.2"
  104. docteur-solo5
  105. docteur-unix >= "0.0.5"
  106. doi2bib
  107. dream
  108. dream-httpaf
  109. dream-pure
  110. dream-serve
  111. dropbox
  112. dune >= "3.17.2"
  113. dune-rpc-lwt
  114. earlybird
  115. elasticsearch-cli
  116. emoji = "2.0.0"
  117. equinoxe
  118. ethernet
  119. ez_api >= "1.2.0"
  120. ezcurl-lwt
  121. ezjs_min < "0.2"
  122. ezjsonm-lwt
  123. ezresto
  124. faraday-lwt
  125. faraday-lwt-unix
  126. fat-filesystem
  127. fiber-lwt
  128. fsevents-lwt
  129. fswatch_lwt
  130. gdbprofiler
  131. git
  132. git-cohttp
  133. git-cohttp-unix
  134. git-kv >= "0.2.0"
  135. git-mirage
  136. git-paf
  137. git-unix >= "3.2.0"
  138. github
  139. github-hooks
  140. github-unix >= "4.4.0"
  141. gitlab-unix
  142. gitlab_pipeline_notifier
  143. gluten-lwt
  144. gluten-lwt-unix < "0.4.0"
  145. gluten-mirage < "0.4.0"
  146. graphql-lwt
  147. gremlin
  148. grpc-lwt
  149. guardian
  150. gufo
  151. h1
  152. h1-lwt-unix
  153. h2-lwt
  154. h2-lwt-unix < "0.10.0"
  155. h2-mirage
  156. happy-eyeballs-lwt
  157. happy-eyeballs-mirage
  158. hidapi-lwt
  159. hiredis >= "0.6"
  160. hl_yaml
  161. hockmd
  162. http-lwt-client
  163. http-mirage-client
  164. http-multipart-formdata >= "2.0.0" & < "3.0.0"
  165. httpaf-lwt-unix
  166. httpun-lwt
  167. httpun-mirage
  168. httpun-ws-lwt
  169. hvsock
  170. i3ipc
  171. influxdb-lwt
  172. inotify >= "2.4"
  173. inquire < "0.3.0"
  174. interface-prime-lwt
  175. ip2location
  176. ip2locationio
  177. ip2whois
  178. ipv6-multicast-lwt
  179. irc-client-lwt
  180. irc-client-lwt-ssl
  181. irc-client-tls
  182. irmin
  183. irmin-bench
  184. irmin-chunk
  185. irmin-cli
  186. irmin-client
  187. irmin-containers
  188. irmin-fs
  189. irmin-git
  190. irmin-graphql
  191. irmin-http
  192. irmin-indexeddb
  193. irmin-layers
  194. irmin-mirage-git
  195. irmin-mirage-graphql
  196. irmin-pack
  197. irmin-server
  198. irmin-test
  199. irmin-unix
  200. irmin-watcher
  201. joolog
  202. jose < "0.9.0"
  203. js_of_ocaml-lwt >= "3.5.0"
  204. jsoo_broadcastchannel
  205. jsoo_storage
  206. jupyter
  207. jupyter-kernel
  208. kafka < "0.5"
  209. kafka_lwt
  210. kappa-library
  211. ke >= "0.5"
  212. kinetic-client
  213. kubecaml
  214. lambda-runtime
  215. lambda-term >= "3.3.3"
  216. lambda_streams_lwt
  217. launchd
  218. ldp
  219. learn-ocaml
  220. learn-ocaml-client
  221. ledgerwallet >= "0.4.0"
  222. letsencrypt
  223. letsencrypt-app
  224. letsencrypt-dns
  225. letters
  226. lichess_api
  227. links >= "0.9.1"
  228. llama
  229. lru_cache
  230. lwt-canceler
  231. lwt-dllist
  232. lwt-exit
  233. lwt-parallel
  234. lwt-pipe
  235. lwt-pipeline
  236. lwt-watcher
  237. lwt_camlp4
  238. lwt_direct >= "6.0.0"
  239. lwt_ppx >= "6.0.0"
  240. lwt_react
  241. lwt_retry
  242. lwt_ssl
  243. mariadb >= "1.2.0"
  244. markdown_monolith
  245. markup = "0.7.6"
  246. markup-lwt
  247. mdx
  248. mechaml
  249. mehari-lwt-unix
  250. mehari-mirage
  251. memtrace-mirage
  252. metrics-influx
  253. metrics-lwt
  254. metrics-unix
  255. mimic
  256. mindstorm-lwt
  257. mirage < "4.0.0"
  258. mirage-block >= "2.0.1"
  259. mirage-block-ccm
  260. mirage-block-combinators
  261. mirage-block-lwt
  262. mirage-block-partition
  263. mirage-block-ramdisk
  264. mirage-block-solo5
  265. mirage-block-unikraft
  266. mirage-block-unix >= "2.14.2"
  267. mirage-block-xen
  268. mirage-channel >= "4.0.1"
  269. mirage-channel-lwt
  270. mirage-clock-lwt
  271. mirage-clock-unix < "4.2.0"
  272. mirage-console-lwt
  273. mirage-crypto-rng < "0.11.3"
  274. mirage-crypto-rng-lwt
  275. mirage-crypto-rng-mirage
  276. mirage-device >= "2.0.0"
  277. mirage-flow >= "3.0.0"
  278. mirage-flow-combinators
  279. mirage-flow-lwt
  280. mirage-flow-unix
  281. mirage-fs >= "4.0.0"
  282. mirage-fs-lwt
  283. mirage-kv >= "3.0.1"
  284. mirage-kv-lwt
  285. mirage-kv-unix
  286. mirage-net >= "4.0.0"
  287. mirage-net-lwt
  288. mirage-net-macosx
  289. mirage-net-solo5
  290. mirage-net-unikraft
  291. mirage-net-unix
  292. mirage-net-xen
  293. mirage-profile
  294. mirage-protocols >= "7.0.0"
  295. mirage-protocols-lwt
  296. mirage-qubes
  297. mirage-qubes-ipv4
  298. mirage-sleep
  299. mirage-solo5
  300. mirage-stack = "3.0.0"
  301. mirage-stack-lwt
  302. mirage-time >= "3.0.0"
  303. mirage-time-lwt
  304. mirage-time-unix
  305. mirage-types-lwt
  306. mirage-unikraft
  307. mirage-unix
  308. mirage-vnetif
  309. mirage-xen
  310. monorobot
  311. mqtt
  312. mrmime >= "0.5.0"
  313. multipart-form-data
  314. multipart_form >= "0.2.0" & < "0.4.0"
  315. multipart_form-cohttp-lwt < "0.6.0"
  316. multipart_form-lwt
  317. naboris
  318. nbd >= "4.0.3"
  319. nbd-tool
  320. nbd-unix
  321. neo4j_bolt
  322. nottui-lwt
  323. notty-community
  324. nproc
  325. nsq
  326. obuilder
  327. obus >= "1.2.1"
  328. ocluster-api
  329. ocluster-worker
  330. ocplib-resto
  331. ocsigenserver
  332. ocsipersist
  333. ocsipersist-dbm
  334. ocsipersist-lib
  335. ocsipersist-pgsql
  336. ocsipersist-sqlite
  337. oframl
  338. ojs_base
  339. omigrate
  340. oneffs
  341. opam-check-npm-deps >= "4.1.0"
  342. opencage
  343. opentelemetry-client-cohttp-lwt
  344. opentelemetry-cohttp-lwt >= "0.4"
  345. opentelemetry-lwt
  346. opium
  347. opium-graphql
  348. opium_kernel
  349. opomodoro
  350. order-i3-xfce
  351. ordma
  352. oskel >= "0.3.0"
  353. ounit-lwt < "2.2.0"
  354. ounit2-lwt
  355. owork
  356. ozulip
  357. paf
  358. paf-cohttp
  359. passage < "0.1.8"
  360. pcap-format < "0.5.2"
  361. petrol
  362. pgn_parser
  363. pgx_lwt
  364. pgx_lwt_mirage
  365. pgx_lwt_unix < "2.0"
  366. piaf < "0.2.0"
  367. picos_meta
  368. plebeia >= "2.0.0"
  369. plotkicadsch
  370. ppx_defer >= "0.4.0"
  371. ppx_deriving_rpc
  372. ppx_rapper_lwt
  373. proc-smaps
  374. prof_spacetime
  375. prometheus
  376. prometheus-app
  377. promise_jsoo_lwt
  378. protocol-9p
  379. protocol-9p-unix
  380. proton
  381. pxshot
  382. qcow
  383. qcow-stream
  384. qcow-tool
  385. qcow-types
  386. qdrant < "0.2.0"
  387. qfs >= "0.5"
  388. quests
  389. rawlink < "2.1"
  390. rawlink-lwt
  391. rdf_json_ld
  392. rdf_lwt
  393. redis-lwt
  394. reparse-lwt
  395. reparse-lwt-unix
  396. resource-pooling
  397. resp
  398. resp-mirage >= "0.10.0"
  399. resp-unix >= "0.10.0"
  400. resto
  401. resto-cohttp-client = "0.4"
  402. resto-cohttp-server = "0.4"
  403. resto-directory = "0.4"
  404. riak
  405. ringo-lwt
  406. river
  407. rock
  408. rpclib-js
  409. rpclib-lwt
  410. SZXX < "4.0.0"
  411. sanddb
  412. scgi
  413. sendmail-lwt
  414. sendmail-mirage
  415. serial
  416. server-reason-react
  417. session-cohttp-lwt
  418. session-cookie-lwt
  419. session-postgresql-lwt
  420. sessions
  421. shared-block-ring
  422. shared-memory-ring-lwt
  423. sherlodoc
  424. sihl < "0.2.0"
  425. slack
  426. slacko
  427. slipshow
  428. smtml >= "0.7.0"
  429. speed
  430. spin < "0.8.0"
  431. spoke
  432. statocaml
  433. stk
  434. stog
  435. swapfs
  436. syguslib-utils
  437. syndic >= "1.4" & < "1.6.0"
  438. tar-mirage
  439. tar-unix
  440. tcpip
  441. telegraml
  442. terminus
  443. testcontainers
  444. testo-lwt
  445. tidy_email
  446. tls >= "0.10.6" & < "0.16.0"
  447. tls-lwt
  448. tls-mirage
  449. tube
  450. tuntap
  451. twirp_cohttp_lwt_unix
  452. uring
  453. uspf
  454. uspf-lwt
  455. uspf-mirage
  456. utcp
  457. utop
  458. uwt
  459. vchan
  460. vchan-unix
  461. vchan-xen
  462. vercel
  463. vhd-format-lwt
  464. vmnet
  465. vpnkit
  466. vue-jsoo < "0.3"
  467. wayland < "2.0"
  468. webauthn
  469. xen-evtchn
  470. xen-evtchn-unix
  471. xen-gnt
  472. xen-gnt-unix
  473. xenstore
  474. xenstore-tool
  475. xenstore_transport
  476. xlsx2csv
  477. yocaml_git
  478. yocaml_unix < "2.0.0"
  479. zarr-lwt
  480. zmq-lwt >= "5.2.1"

Conflicts

None