diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,12 @@
-## [_Unreleased_](https://github.com/freckle/freckle-app/compare/v1.10.1.0...main)
+## [_Unreleased_](https://github.com/freckle/freckle-app/compare/v1.10.2.0...main)
 
-## [v1.10.0.1](https://github.com/freckle/freckle-app/compare/v1.10.0.0...v1.10.1.0)
+## [v1.10.2.0](https://github.com/freckle/freckle-app/compare/v1.10.1.0...v1.10.2.0)
+
+- Add module `Freckle.App.Memcached.MD5`
+- Add `fiveMinuteTTL` to module `Freckle.App.Memcached.CacheTTL`
+- Add `cachingAsCBOR` to module `Freckle.App.Memcached`
+
+## [v1.10.1.1](https://github.com/freckle/freckle-app/compare/v1.10.0.0...v1.10.1.0)
 
 - Use `withTraceIdContext` in `Freckle.App.Kafka.Consumer.runConsumer`, ensuring
   all logging contains the `trace_id` in context.
diff --git a/freckle-app.cabal b/freckle-app.cabal
--- a/freckle-app.cabal
+++ b/freckle-app.cabal
@@ -1,6 +1,6 @@
 cabal-version:      1.18
 name:               freckle-app
-version:            1.10.1.0
+version:            1.10.2.0
 license:            MIT
 license-file:       LICENSE
 maintainer:         Freckle Education
@@ -45,6 +45,7 @@
         Freckle.App.Memcached.CacheKey
         Freckle.App.Memcached.CacheTTL
         Freckle.App.Memcached.Client
+        Freckle.App.Memcached.MD5
         Freckle.App.Memcached.Servers
         Freckle.App.OpenTelemetry
         Freckle.App.Prelude
@@ -85,80 +86,82 @@
         -Wno-safe -Wno-unsafe
 
     build-depends:
-        Blammo,
-        Glob,
-        MonadRandom,
-        aeson,
-        aws-xray-client-persistent,
-        aws-xray-client-wai,
-        base,
-        bcp47,
-        bugsnag,
-        bytestring,
-        case-insensitive,
-        cassava,
-        conduit,
-        conduit-extra,
-        containers,
-        cookie,
-        datadog,
-        doctest,
-        dotenv,
-        ekg-core,
-        envparse,
-        errors,
-        exceptions,
-        extra,
-        filepath,
-        hashable,
-        hs-opentelemetry-api,
-        hs-opentelemetry-instrumentation-persistent,
-        hs-opentelemetry-instrumentation-wai,
-        hs-opentelemetry-propagator-datadog,
-        hs-opentelemetry-sdk,
+        Blammo >=1.0.2.2,
+        Glob >=0.10.2,
+        MonadRandom >=0.5.3,
+        aeson >=1.5.6.0,
+        aws-xray-client-persistent >=0.1.0.5,
+        aws-xray-client-wai >=0.1.0.2,
+        base >=4.14.3.0,
+        bcp47 >=0.2.0.6,
+        bugsnag >=1.0.0.0,
+        bytestring >=0.10.12.0,
+        case-insensitive >=1.2.1.0,
+        cassava >=0.5.2.0,
+        conduit >=1.3.4.2,
+        conduit-extra >=1.3.5,
+        containers >=0.6.5.1,
+        cookie >=0.4.5,
+        datadog >=0.2.5.0,
+        doctest >=0.17,
+        dotenv >=0.8.0.7,
+        ekg-core >=0.1.1.7,
+        envparse >=0.5.0,
+        errors >=2.3.0,
+        exceptions >=0.10.4,
+        extra >=1.7.9,
+        filepath >=1.4.2.1,
+        hashable >=1.3.0.0,
+        hs-opentelemetry-api >=0.1.0.0,
+        hs-opentelemetry-instrumentation-persistent >=0.1.0.0,
+        hs-opentelemetry-instrumentation-wai >=0.1.0.0,
+        hs-opentelemetry-propagator-datadog >=0.0.0.0,
+        hs-opentelemetry-sdk >=0.0.3.6,
         hspec >=2.8.1,
         hspec-core >=2.8.1,
-        hspec-expectations-lifted,
+        hspec-expectations-lifted >=0.10.0,
         hspec-junit-formatter >=1.1.0.1,
-        http-client,
+        http-client >=0.6.4.1,
         http-conduit >=2.3.5,
-        http-link-header,
-        http-types,
+        http-link-header >=1.2.1,
+        http-types >=0.12.3,
         hw-kafka-client >=4.0.3 && <5.0.0,
-        immortal,
-        lens,
-        memcache,
-        monad-control,
-        monad-validate,
-        mtl,
-        network-uri,
-        nonempty-containers,
-        path-pieces,
-        persistent,
-        persistent-postgresql,
-        postgresql-simple,
-        primitive,
+        immortal >=0.3,
+        lens >=4.19.2,
+        memcache >=0.3.0.1,
+        monad-control >=1.0.3.1,
+        monad-validate >=1.2.0.1,
+        mtl >=2.2.2,
+        network-uri >=2.6.4.1,
+        nonempty-containers >=0.3.4.4,
+        path-pieces >=0.2.1,
+        persistent >=2.13.3.0,
+        persistent-postgresql >=2.13.4.0,
+        postgresql-simple >=0.6.4,
+        primitive >=0.7.3.0,
+        pureMD5 >=2.1.4,
         resource-pool >=0.4.0.0,
-        resourcet,
+        resourcet >=1.2.4.3,
         retry >=0.8.1.0,
-        safe,
-        scientist,
-        semigroupoids,
-        template-haskell,
-        text,
-        time,
-        transformers,
-        transformers-base,
-        typed-process,
-        unliftio,
-        unliftio-core,
-        unordered-containers,
-        vector,
-        wai,
-        wai-extra,
-        yaml,
-        yesod-core,
-        yesod-test
+        safe >=0.3.19,
+        scientist >=0.0.0.0,
+        semigroupoids >=5.3.7,
+        serialise >=0.2.4.0,
+        template-haskell >=2.16.0.0,
+        text >=1.2.4.1,
+        time >=1.9.3,
+        transformers >=0.5.6.2,
+        transformers-base >=0.4.6,
+        typed-process >=0.2.8.0,
+        unliftio >=0.2.21.0,
+        unliftio-core >=0.2.0.1,
+        unordered-containers >=0.2.16.0,
+        vector >=0.12.3.1,
+        wai >=3.2.3,
+        wai-extra >=3.1.8,
+        yaml >=0.11.8.0,
+        yesod-core >=1.6.21.0,
+        yesod-test >=1.6.12
 
     if impl(ghc >=9.2)
         ghc-options: -Wno-missing-kind-signatures
@@ -239,28 +242,28 @@
         -Wno-safe -Wno-unsafe -threaded -rtsopts -with-rtsopts=-N
 
     build-depends:
-        Blammo,
-        QuickCheck,
-        aeson,
+        Blammo >=1.0.2.2,
+        QuickCheck >=2.14.2,
+        aeson >=1.5.6.0,
         base >=4.14.3.0 && <5,
-        bugsnag,
-        bytestring,
-        cassava,
-        conduit,
-        errors,
+        bugsnag >=1.0.0.0,
+        bytestring >=0.10.12.0,
+        cassava >=0.5.2.0,
+        conduit >=1.3.4.2,
+        errors >=2.3.0,
         freckle-app,
-        hspec,
-        http-types,
-        lens,
-        lens-aeson,
-        memcache,
-        monad-validate,
-        nonempty-containers,
-        postgresql-simple,
-        unliftio,
-        vector,
-        wai,
-        wai-extra
+        hspec >=2.9.3,
+        http-types >=0.12.3,
+        lens >=4.19.2,
+        lens-aeson >=1.1.3,
+        memcache >=0.3.0.1,
+        monad-validate >=1.2.0.1,
+        nonempty-containers >=0.3.4.4,
+        postgresql-simple >=0.6.4,
+        unliftio >=0.2.21.0,
+        vector >=0.12.3.1,
+        wai >=3.2.3,
+        wai-extra >=3.1.8
 
     if impl(ghc >=9.2)
         ghc-options: -Wno-missing-kind-signatures
diff --git a/library/Freckle/App/Memcached.hs b/library/Freckle/App/Memcached.hs
--- a/library/Freckle/App/Memcached.hs
+++ b/library/Freckle/App/Memcached.hs
@@ -13,16 +13,19 @@
   , caching
   , cachingAs
   , cachingAsJSON
+  , cachingAsCBOR
 
     -- * Re-exports
   , module Freckle.App.Memcached.Client
   , module Freckle.App.Memcached.CacheKey
   , module Freckle.App.Memcached.CacheTTL
+  , module Freckle.App.Memcached.MD5
   ) where
 
 import Freckle.App.Prelude
 
 import Blammo.Logging
+import Codec.Serialise (Serialise, deserialiseOrFail, serialise)
 import Data.Aeson
 import Data.ByteString (ByteString)
 import qualified Data.ByteString.Lazy as BSL
@@ -31,6 +34,7 @@
 import Freckle.App.Memcached.CacheKey
 import Freckle.App.Memcached.CacheTTL
 import Freckle.App.Memcached.Client (HasMemcachedClient (..))
+import Freckle.App.Memcached.MD5
 import qualified Freckle.App.Memcached.Client as Memcached
 import UnliftIO.Exception (Exception (..), handleAny)
 
@@ -109,6 +113,23 @@
   -> m a
   -> m a
 cachingAsJSON = cachingAs eitherDecodeStrict encodeStrict
+
+-- | Cache data in memcached in CBOR format
+cachingAsCBOR
+  :: ( MonadUnliftIO m
+     , MonadLogger m
+     , MonadReader env m
+     , HasMemcachedClient env
+     , Serialise a
+     )
+  => CacheKey
+  -> CacheTTL
+  -> m a
+  -> m a
+cachingAsCBOR =
+  cachingAs
+    (first show . deserialiseOrFail . BSL.fromStrict)
+    (BSL.toStrict . serialise)
 
 handleCachingError
   :: (MonadUnliftIO m, MonadLogger m) => a -> Text -> m a -> m a
diff --git a/library/Freckle/App/Memcached/CacheTTL.hs b/library/Freckle/App/Memcached/CacheTTL.hs
--- a/library/Freckle/App/Memcached/CacheTTL.hs
+++ b/library/Freckle/App/Memcached/CacheTTL.hs
@@ -2,6 +2,7 @@
   ( CacheTTL
   , cacheTTL
   , fromCacheTTL
+  , fiveMinuteTTL
   ) where
 
 import Freckle.App.Prelude
@@ -27,3 +28,7 @@
 
   maxWord :: Word32
   maxWord = maxBound
+
+-- | Standard 5 minute time to live
+fiveMinuteTTL :: CacheTTL
+fiveMinuteTTL = cacheTTL $ 5 * 60
diff --git a/library/Freckle/App/Memcached/MD5.hs b/library/Freckle/App/Memcached/MD5.hs
new file mode 100644
--- /dev/null
+++ b/library/Freckle/App/Memcached/MD5.hs
@@ -0,0 +1,21 @@
+module Freckle.App.Memcached.MD5
+  ( md5CacheKey
+  , md5Key
+  , md5Text
+  ) where
+
+import Freckle.App.Prelude
+
+import qualified Data.ByteString.Lazy as BSL
+import qualified Data.Digest.Pure.MD5 as Digest
+import Freckle.App.Memcached.CacheKey
+
+md5CacheKey :: Show a => a -> CacheKey
+md5CacheKey = either (error "md5 is always cacheable") id . cacheKey . md5Key
+
+-- | Pack any showable into an md5 encoded text
+md5Key :: Show a => a -> Text
+md5Key = md5Text . pack . show
+
+md5Text :: Text -> Text
+md5Text = pack . show . Digest.md5 . BSL.fromStrict . encodeUtf8
diff --git a/package.yaml b/package.yaml
--- a/package.yaml
+++ b/package.yaml
@@ -1,5 +1,5 @@
 name: freckle-app
-version: 1.10.1.0
+version: 1.10.2.0
 maintainer: Freckle Education
 category: Utils
 github: freckle/freckle-app
@@ -121,12 +121,14 @@
     - persistent-postgresql
     - postgresql-simple
     - primitive
+    - pureMD5
     - resource-pool >= 0.4.0.0 # defaultPoolConfig, etc
     - resourcet
     - retry >= 0.8.1.0 # retryingDynamic
     - safe
     - scientist
     - semigroupoids
+    - serialise
     - template-haskell
     - text
     - time
