diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Revision history for lz4-bytes
 
+## 0.2.1.0 -- 2026-07-14
+
+* Support fast compression for frames
+
 ## 0.2.0.0 -- 2025-07-07
 
 * Make it possible to compress much larger buffers as a frame
diff --git a/lz4-bytes.cabal b/lz4-bytes.cabal
--- a/lz4-bytes.cabal
+++ b/lz4-bytes.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.2
 name:               lz4-bytes
-version:            0.2.0.0
+version:            0.2.1.0
 synopsis:           Bindings to LZ4
 description:
   This library is similar to the @lz4@ library except that it works
@@ -45,7 +45,7 @@
   hs-source-dirs:  src
   include-dirs: cbits
   ghc-options: -O2 -Wall
-  cc-options: -Wall
+  cc-options: -Wall -O3
   c-sources:
     cbits/hs_lz4.c
     cbits/lz4.c
@@ -69,4 +69,4 @@
 
 source-repository head
   type:     git
-  location: git://github.com/byteverse/lz4-bytes.git
+  location: ssh://github.com/byteverse/lz4-bytes.git
diff --git a/src/Lz4/Block.hs b/src/Lz4/Block.hs
--- a/src/Lz4/Block.hs
+++ b/src/Lz4/Block.hs
@@ -27,7 +27,7 @@
   , requiredBufferSize
   ) where
 
-import Lz4.Internal (requiredBufferSize,c_hs_compress_HC,c_hs_decompress_safe)
+import Lz4.Internal (requiredBufferSize,c_hs_compress_HC,c_hs_decompress_safe,c_hs_compress_fast)
 
 import Control.Monad.ST (runST)
 import Control.Monad.ST.Run (runByteArrayST)
@@ -166,22 +166,6 @@
       pure (Just result)
     else pure Nothing
 
-foreign import ccall unsafe "hs_compress_fast"
-  c_hs_compress_fast ::
-    ByteArray# -> -- Source
-    Int -> -- Source offset
-    MutableByteArray# s -> -- Destination
-    Int -> -- Destination offset
-    Int -> -- Input size
-    Int -> -- Destination capacity
-    Int -> -- Acceleration factor
-    IO Int -- Result length
-
 data Lz4BufferTooSmall = Lz4BufferTooSmall
   deriving stock (Eq, Show)
   deriving anyclass (Control.Exception.Exception)
-
--- foreign import capi "lz4.h value sizeof(LZ4_stream_t)" lz4StreamSz :: Int
---
--- allocateLz4StreamT :: ST s (MutableByteArray s)
--- allocateLz4StreamT = PM.newPinnedByteArray lz4StreamSz
diff --git a/src/Lz4/Frame.hs b/src/Lz4/Frame.hs
--- a/src/Lz4/Frame.hs
+++ b/src/Lz4/Frame.hs
@@ -14,11 +14,12 @@
 module Lz4.Frame
   ( -- * Compression
     compressHighlyU
+  , compressU
     -- * Decompression
   , decompressU
   ) where
 
-import Lz4.Internal (requiredBufferSize,c_hs_compress_HC,c_hs_decompress_safe,DecompressionContext)
+import Lz4.Internal (requiredBufferSize,c_hs_compress_HC,c_hs_compress_fast,c_hs_decompress_safe,DecompressionContext)
 import Lz4.Internal (c_LZ4F_createDecompressionContext, c_hs_decompress_frame)
 import Lz4.Internal (c_LZ4F_freeDecompressionContext)
 import Foreign.C.Types (CSize)
@@ -120,12 +121,6 @@
 {- | Use HC compression to produce a frame with a single block.
 All optional fields (checksums, content sizes, and dictionary IDs)
 are omitted.
-
-Note: Currently, this produces incorrect output when the size of
-the input to be compressed is greater than 4MiB. The only way
-to correct this function is to make it not compress large input.
-This can be done by setting the high bit of the size. This needs
-to be tested though since it is an uncommon code path.
 -}
 compressHighlyU ::
   -- | Compression level (Use 9 if uncertain)
@@ -133,7 +128,28 @@
   -- | Bytes to compress
   Bytes ->
   ByteArray
-compressHighlyU !lvl (Bytes (ByteArray arr) off0 len0) = runST do
+{-# inline compressHighlyU #-}
+compressHighlyU = compressGeneralU 1
+
+compressU ::
+  -- | Acceleration factor (Use 1 if uncertain, higher values increase speed and reduce compression)
+  Int ->
+  -- | Bytes to compress
+  Bytes ->
+  ByteArray
+{-# inline compressU #-}
+compressU = compressGeneralU 0
+
+compressGeneralU ::
+  -- Is HC (0 means fast, anything else means HC)
+  Word32 ->
+  -- Compression level (meanings vary for HC and fast)
+  Int ->
+  -- Bytes to compress
+  Bytes ->
+  ByteArray
+{-# noinline compressGeneralU #-}
+compressGeneralU !isHc !lvl (Bytes (ByteArray arr) off0 len0) = runST do
   let maxSz = requiredBufferSize len0 + 15
   dst@(MutableByteArray dst#) <- PM.newByteArray maxSz
   -- -- First 4 bytes: magic identifier
@@ -158,7 +174,9 @@
         PM.writeByteArray dst 6 (0x73 :: Word8)
   let handleBlocks !ix !inputOff !inputRemaining = do
         let !inputClipped = min inputRemaining 4_194_304
-        actualSz <- unsafeIOToST (c_hs_compress_HC arr inputOff dst# (ix + 4) inputClipped maxSz lvl)
+        actualSz <- case isHc of
+          0 -> unsafeIOToST (c_hs_compress_fast arr inputOff dst# (ix + 4) inputClipped maxSz lvl)
+          _ -> unsafeIOToST (c_hs_compress_HC arr inputOff dst# (ix + 4) inputClipped maxSz lvl)
         case actualSz of
           0 -> errorWithoutStackTrace "Lz4.Frame.compressHighlyU: compression failed"
           _ -> do
diff --git a/src/Lz4/Internal.hs b/src/Lz4/Internal.hs
--- a/src/Lz4/Internal.hs
+++ b/src/Lz4/Internal.hs
@@ -10,6 +10,7 @@
   ( DecompressionContext
   , requiredBufferSize
   , c_hs_compress_HC
+  , c_hs_compress_fast
   , c_hs_decompress_safe
   , c_hs_decompress_frame
   , c_LZ4F_createDecompressionContext
@@ -31,6 +32,17 @@
 
 foreign import ccall unsafe "hs_compress_HC"
   c_hs_compress_HC ::
+    ByteArray# -> -- Source
+    Int -> -- Source offset
+    MutableByteArray# s -> -- Destination
+    Int -> -- Destination offset
+    Int -> -- Input size
+    Int -> -- Destination capacity
+    Int -> -- Compression level
+    IO Int -- Result length
+
+foreign import ccall unsafe "hs_compress_fast"
+  c_hs_compress_fast ::
     ByteArray# -> -- Source
     Int -> -- Source offset
     MutableByteArray# s -> -- Destination
