diff --git a/nix/sources.json b/nix/sources.json
index 61f2d6ec8aab8223eca33745e2b34d850ce9477f..0068d8839a888b40002b3367e73a7752e2008b27 100644
--- a/nix/sources.json
+++ b/nix/sources.json
@@ -47,10 +47,10 @@
         "homepage": "https://tahoe-lafs.org/",
         "owner": "tahoe-lafs",
         "repo": "tahoe-lafs",
-        "rev": "4bfb9d21700b8084d5fb2c697ceeb7088dd97c37",
-        "sha256": "1hcp9gq5hcw43xmg7n24xx580jrg0fd382pklv79r5lr4cicyx7g",
+        "rev": "2742de6f7c1fa6cf77e35ecc5854bcf7db3e5963",
+        "sha256": "17bbkk21hfln6gw5lq29g0s3jzbmfwk3921w36shx09i8asfwn56",
         "type": "tarball",
-        "url": "https://github.com/tahoe-lafs/tahoe-lafs/archive/4bfb9d21700b8084d5fb2c697ceeb7088dd97c37.tar.gz",
+        "url": "https://github.com/tahoe-lafs/tahoe-lafs/archive/2742de6f7c1fa6cf77e35ecc5854bcf7db3e5963.tar.gz",
         "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
     }
 }
diff --git a/src/_zkapauthorizer/_storage_server.py b/src/_zkapauthorizer/_storage_server.py
index 392f2ebcd8a7b104369a239c607866601197c01f..68cfcc20ee788211cbd7f23562dd4400da4dde14 100644
--- a/src/_zkapauthorizer/_storage_server.py
+++ b/src/_zkapauthorizer/_storage_server.py
@@ -173,6 +173,19 @@ class ZKAPAuthorizerStorageServer(Referenceable):
         default=attr.Factory(partial(namedAny, "twisted.internet.reactor")),
     )
 
+    def __attrs_post_init__(self):
+        # Avoid the default StorageServer ``allocate_buckets`` behavior of
+        # renewing leases on all existing shares in the same bucket.  It will
+        # still add leases to the newly uploaded shares.
+        self._original.set_implicit_bucket_lease_renewal(False)
+
+        # Similarly, wrapped ``slot_testv_and_readv_and_writev_message``
+        # renews leases on all shares that are being modified.  Turn that
+        # behavior off.  This means we have to take responsibility for
+        # creating the initial lease on shares when they are created (and we
+        # do in our wrapper for ``slot_testv_and_readv_and_writev_message``).
+        self._original.set_implicit_slot_lease_renewal(False)
+
     def remote_get_version(self):
         """
         Pass-through without pass check to allow clients to learn about our
@@ -202,7 +215,7 @@ class ZKAPAuthorizerStorageServer(Referenceable):
 
         # Note: The *allocate_buckets* protocol allows for some shares to
         # already exist on the server.  When this is the case, the cost of the
-        # operation is based only on the buckets which are really allocated
+        # operation is based only on the shares which are really allocated
         # here.  It's not clear if we can allow the client to supply the
         # reduced number of passes in the call but we can be sure to only mark
         # as spent enough passes to cover the allocated buckets.  The return
@@ -360,6 +373,7 @@ class ZKAPAuthorizerStorageServer(Referenceable):
             if required_new_passes > len(validation.valid):
                 validation.raise_for(required_new_passes)
 
+        self._original.set_implicit_slot_lease_renewal(renew_leases)
         # Skip over the remotely exposed method and jump to the underlying
         # implementation which accepts one additional parameter that we know
         # about (and don't expose over the network): renew_leases.  We always
@@ -370,7 +384,6 @@ class ZKAPAuthorizerStorageServer(Referenceable):
             secrets,
             tw_vectors,
             r_vector,
-            renew_leases=renew_leases,
         )
 
     def remote_slot_readv(self, *a, **kw):
diff --git a/src/_zkapauthorizer/tests/foolscap.py b/src/_zkapauthorizer/tests/foolscap.py
index 3a984bea163fd4c567812556f8229508c0cb8a2d..52b745a6a0b50d154388b0a96aee3b3c20f59fb8 100644
--- a/src/_zkapauthorizer/tests/foolscap.py
+++ b/src/_zkapauthorizer/tests/foolscap.py
@@ -37,8 +37,11 @@ class RIEcho(RemoteInterface):
 
 @implementer(RIStorageServer)
 class StubStorageServer(object):
-    pass
+    def set_implicit_bucket_lease_renewal(self, enabled):
+        pass
 
+    def set_implicit_slot_lease_renewal(self, enabled):
+        pass
 
 def get_anonymous_storage_server():
     return StubStorageServer()
diff --git a/src/_zkapauthorizer/tests/test_storage_protocol.py b/src/_zkapauthorizer/tests/test_storage_protocol.py
index a77dc29266a905226ea7a38c2d9bd13f7fc96072..8d9b89e366825dc414691d75cc4f47c284b5928c 100644
--- a/src/_zkapauthorizer/tests/test_storage_protocol.py
+++ b/src/_zkapauthorizer/tests/test_storage_protocol.py
@@ -19,6 +19,7 @@ Tests for communication between the client and server components.
 from __future__ import absolute_import
 
 from allmydata.storage.common import storage_index_to_dir
+from allmydata.storage.shares import get_share_file
 from challenge_bypass_ristretto import random_signing_key
 from fixtures import MonkeyPatch
 from foolscap.referenceable import LocalReferenceable
@@ -357,6 +358,8 @@ class ShareTests(TestCase):
         cancel_secret=lease_cancel_secrets(),
         existing_sharenums=sharenum_sets(),
         additional_sharenums=sharenum_sets(),
+        when=posix_timestamps(),
+        interval=integers(min_value=1, max_value=60 * 60 * 24 * 31),
         size=sizes(),
     )
     def test_shares_already_exist(
@@ -366,6 +369,8 @@ class ShareTests(TestCase):
         cancel_secret,
         existing_sharenums,
         additional_sharenums,
+        when,
+        interval,
         size,
     ):
         """
@@ -374,14 +379,22 @@ class ShareTests(TestCase):
         """
         # A helper that only varies on sharenums.
         def allocate_buckets(sharenums):
-            return self.client.allocate_buckets(
-                storage_index,
-                renew_secret,
-                cancel_secret,
-                sharenums,
-                size,
-                canary=self.canary,
+            alreadygot, writers = extract_result(
+                self.client.allocate_buckets(
+                    storage_index,
+                    renew_secret,
+                    cancel_secret,
+                    sharenums,
+                    size,
+                    canary=self.canary,
+                ),
             )
+            for sharenum, writer in writers.items():
+                writer.remote_write(0, bytes_for_share(sharenum, size))
+                writer.remote_close()
+
+        # Set some arbitrary time so we can inspect lease renewal behavior.
+        self.clock.advance(when)
 
         # Create some shares to alter the behavior of the next
         # allocate_buckets.
@@ -395,14 +408,15 @@ class ShareTests(TestCase):
             canary=self.canary,
         )
 
+        # Let some time pass so leases added after this point will look
+        # different from leases added before this point.
+        self.clock.advance(interval)
+
         # Do a partial repeat of the operation.  Shuffle around
         # the shares in some random-ish way.  If there is partial overlap
         # there should be partial spending.
         all_sharenums = existing_sharenums | additional_sharenums
-        self.assertThat(
-            allocate_buckets(all_sharenums),
-            succeeded(Always()),
-        )
+        allocate_buckets(all_sharenums)
 
         # This is what the client should try to spend.  This should also match
         # the total number of passes issued during the test.
@@ -435,6 +449,23 @@ class ShareTests(TestCase):
             ),
         )
 
+        def get_lease_grant_times(storage_server, storage_index):
+            for sharenum, sharepath in storage_server._get_bucket_shares(storage_index):
+                yield sharenum, list(lease.get_grant_renew_time_time() for lease in get_share_file(sharepath).get_leases())
+
+        expected_leases = {}
+        # Chop off the non-integer part of the expected values because share
+        # files only keep integer precision.
+        expected_leases.update({sharenum: [int(when)] for sharenum in existing_sharenums})
+        expected_leases.update({
+            sharenum: [int(when + interval)] for sharenum in all_sharenums - existing_sharenums
+        })
+
+        self.assertThat(
+            dict(get_lease_grant_times(self.anonymous_storage_server, storage_index)),
+            Equals(expected_leases),
+        )
+
     @given(
         storage_index=storage_indexes(),
         renew_secrets=tuples(lease_renew_secrets(), lease_renew_secrets()),