--- src/lib.rs.before
+++ src/lib.rs
@@ -19,13 +19,24 @@
 type Link = Rc<RefCell<Connection>>;
 type Request = Rc<RefCell<RequestState>>;
 
-fn ready(py: Python<'_>, value: Py<PyAny>, state: Option<&State>) -> PyResult<Py<PyAny>> {
-    let yield_first = state.is_some_and(|s| {
-        let n = s.sends.get() + 1;
-        s.sends.set(if n >= 128 { 0 } else { n });
-        n >= 128
-    });
-    completed::value(py, Some(value), yield_first, state)
+// Fairness belongs to the producing request. Unrelated short requests must
+// not spend each other's quota and delay cleanup after an already-written body.
+fn cooperate(request: &Request) -> bool {
+    let mut r = request.borrow_mut();
+    r.operations += 1;
+    if r.operations < 128 {
+        return false;
+    }
+    r.operations = 0;
+    true
+}
+fn ready(
+    py: Python<'_>,
+    value: Py<PyAny>,
+    request: &Request,
+    state: Option<&State>,
+) -> PyResult<Py<PyAny>> {
+    completed::value(py, Some(value), cooperate(request), state)
 }
 fn message(py: Python<'_>, kind: &str, body: Option<(Py<PyBytes>, bool)>) -> PyResult<Py<PyAny>> {
     let d = PyDict::new(py);
@@ -156,6 +167,7 @@
     head: bool,
     minor: u8,
     task_done: bool,
+    operations: usize,
     trailers: bool,
     body_finished: bool,
     trailers_started: bool,
@@ -173,7 +185,7 @@
     connections: RefCell<HashMap<u64, Link>>,
     tasks: RefCell<HashMap<u64, Py<PyAny>>>,
     next: Cell<u64>,
-    sends: Cell<usize>,
+    eager_left: Cell<usize>,
     stopping: Cell<bool>,
     date: RefCell<Vec<u8>>,
     date_at: Cell<u64>,
@@ -570,6 +582,7 @@
             head: h.method == "HEAD",
             minor: h.minor,
             task_done: false,
+            operations: 0,
             trailers: false,
             body_finished: false,
             trailers_started: false,
@@ -598,7 +611,9 @@
                 .bind(py)
                 .call_method0(pyo3::intern!(py, "get_task_factory"))?
                 .is_none()
+                && self.eager_left.get() > 0
             {
+                self.eager_left.set(self.eager_left.get() - 1);
                 self.task_type
                     .bind(py)
                     .call((coro,), Some(self.task_options.bind(py)))?
@@ -1000,10 +1015,7 @@
         } else {
             return Err(PyValueError::new_err("Unsupported ASGI message"));
         }
-        let n = s.sends.get() + 1;
-        s.sends.set(n);
-        if n >= 128 {
-            s.sends.set(0);
+        if cooperate(&self.request) {
             return completed::value(py, None, true, Some(&s));
         }
         Ok(s.done.clone_ref(py))
@@ -1019,13 +1031,28 @@
 impl Receiver {
     fn __call__(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
         let Some(s) = self.state.upgrade() else {
-            return ready(py, message(py, "http.disconnect", None)?, None);
+            return ready(
+                py,
+                message(py, "http.disconnect", None)?,
+                &self.request,
+                None,
+            );
         };
         let Some(c) = self.request.borrow().connection.upgrade() else {
-            return ready(py, message(py, "http.disconnect", None)?, Some(&s));
+            return ready(
+                py,
+                message(py, "http.disconnect", None)?,
+                &self.request,
+                Some(&s),
+            );
         };
         if c.borrow().dead || self.request.borrow().complete || self.request.borrow().task_done {
-            return ready(py, message(py, "http.disconnect", None)?, Some(&s));
+            return ready(
+                py,
+                message(py, "http.disconnect", None)?,
+                &self.request,
+                Some(&s),
+            );
         }
         s.pump(py, &c)?;
         if !self.request.borrow().body.is_empty()
@@ -1033,7 +1060,7 @@
         {
             let msg = take_message(py, &self.request)?;
             s.pump(py, &c)?;
-            return ready(py, msg, Some(&s));
+            return ready(py, msg, &self.request, Some(&s));
         }
         let old = self.request.borrow_mut().receive.take();
         if let Some(f) = old
@@ -1072,6 +1099,9 @@
 #[pymethods]
 impl Done {
     fn __call__(&self, py: Python<'_>, task: &Bound<'_, PyAny>) -> PyResult<()> {
+        if let Some(s) = self.state.upgrade() {
+            s.eager_left.set(0);
+        }
         self.finish(py, task, true)
     }
 }
@@ -1151,6 +1181,7 @@
 impl Resume {
     fn __call__(&self, py: Python<'_>) -> PyResult<()> {
         if let (Some(s), Some(c)) = (self.state.upgrade(), self.connection.upgrade()) {
+            s.eager_left.set(0);
             c.borrow_mut().resume_scheduled = false;
             s.pump(py, &c)?;
         }
@@ -1218,7 +1249,7 @@
                 connections: RefCell::new(HashMap::new()),
                 tasks: RefCell::new(HashMap::new()),
                 next: Cell::new(0),
-                sends: Cell::new(0),
+                eager_left: Cell::new(0),
                 stopping: Cell::new(false),
                 date: RefCell::new(Vec::new()),
                 date_at: Cell::new(0),
@@ -1236,7 +1267,7 @@
     }
     fn poll(&self, py: Python<'_>) -> PyResult<()> {
         let s = &self.state;
-        s.sends.set(0);
+        s.eager_left.set(0);
         for (token, mask) in s.poller.events()? {
             if token == 0 {
                 if s.stopping.get() {
