El módulo compression.zstd incorpora el formato Zstandard a la biblioteca estándar de Python y ofrece una forma moderna de reducir archivos y secuencias de bytes. Es una opción muy útil para copias de seguridad, registros, cachés, exportaciones de datos, respuestas de red y sistemas que necesitan una buena tasa de compresión sin aceptar procesos demasiado lentos.
En esta guía aprenderás a comprimir bytes, procesar archivos por streaming, elegir niveles, utilizar diccionarios, verificar integridad y limitar la descompresión. Para ampliar el flujo de trabajo, consulta los artículos de Academify sobre archivos ZIP seguros con zipfile, manejo de archivos con pathlib, lectura de archivos gigantes y copiar y mover archivos con shutil.
Qué es Zstandard
Zstandard, también llamado Zstd, es un algoritmo de compresión sin pérdidas diseñado para equilibrar velocidad y tamaño. En muchos conjuntos de texto o datos estructurados consigue archivos menores que gzip con una velocidad similar o superior. Además, admite niveles ajustables, diccionarios reutilizables, cuadros independientes y procesamiento continuo.
La documentación oficial de compression.zstd es la referencia principal para firmas y detalles de cada versión. El formato está estandarizado en la RFC 8878.
Compresión básica de bytes
Cuando el contenido es pequeño, puedes trabajar directamente con bytes. Convierte el texto a UTF-8, comprímelo y luego restáuralo.
from compression import zstd
texto = "Python y compresión Zstandard" * 100
datos = texto.encode("utf-8")
comprimido = zstd.compress(datos)
restaurado = zstd.decompress(comprimido)
print(len(datos), len(comprimido))
print(restaurado.decode("utf-8") == texto)Este método es sencillo, pero el origen y el resultado pueden permanecer simultáneamente en memoria. Para entradas grandes conviene procesar bloques.
Elegir el nivel de compresión
Los niveles altos suelen gastar más CPU para reducir algunos bytes adicionales. Un nivel bajo o medio funciona bien en APIs, cachés y archivos generados con frecuencia. Los niveles superiores pueden ser adecuados para datos archivados una sola vez y descargados muchas veces.
comprimido = zstd.compress(datos, level=6)No decidas únicamente por el tamaño final. Mide duración de compresión, duración de descompresión, memoria, coste de CPU y ahorro de almacenamiento con tus propios datos. JSON, código fuente y volcados de bases de datos se comportan de forma distinta a imágenes o vídeos ya comprimidos.
Archivos grandes mediante streaming
El streaming mantiene estable el consumo de memoria porque lee y escribe bloques acotados.
from pathlib import Path
from compression import zstd
origen = Path("eventos.jsonl")
destino = Path("eventos.jsonl.zst")
with origen.open("rb") as entrada, destino.open("wb") as salida:
with zstd.open(salida, mode="wb", level=5) as compresor:
while bloque := entrada.read(1024 * 1024):
compresor.write(bloque)Un bloque de un megabyte es un punto de partida. Los bloques pequeños aumentan llamadas de función; los enormes elevan la memoria temporal. Prueba varios tamaños y observa dónde aparecen los límites de disco o CPU.
Descompresión segura
Todo archivo recibido desde el exterior debe considerarse no confiable. Un archivo pequeño puede expandirse hasta ocupar muchos gigabytes. Limita la salida, usa rutas controladas, comprueba espacio disponible y elimina archivos parciales si ocurre un error.
from pathlib import Path
from compression import zstd
origen = Path("eventos.jsonl.zst")
destino = Path("eventos-restaurados.jsonl")
limite = 2 * 1024 * 1024 * 1024
escritos = 0
try:
with zstd.open(origen, mode="rb") as lector, destino.open("wb") as escritor:
while bloque := lector.read(1024 * 1024):
escritos += len(bloque)
if escritos > limite:
raise ValueError("La salida supera el límite permitido")
escritor.write(bloque)
except Exception:
destino.unlink(missing_ok=True)
raiseEn servicios web también debes imponer cuotas, tiempo máximo, límite de solicitud y cancelación. Nunca permitas que un nombre proporcionado por el usuario elija libremente la ruta de destino.
Diccionarios de compresión
Los diccionarios son útiles cuando comprimes muchos valores pequeños y parecidos, por ejemplo eventos JSON, telemetría o mensajes que repiten nombres de campos. El entrenamiento captura patrones comunes que serían demasiado cortos para aprenderse dentro de cada elemento.
Reúne muestras representativas, entrena el diccionario, asigna una versión y utiliza exactamente la misma versión al comprimir y descomprimir. El receptor necesita el diccionario correspondiente. Guarda un identificador junto al archivo y conserva versiones antiguas mientras existan datos que dependan de ellas.
Integridad y hashes
La compresión no sustituye una estrategia de integridad. Calcula un hash criptográfico, como SHA-256, y guárdalo en un manifiesto con tamaño original, tamaño comprimido, fecha, algoritmo y versión del diccionario.
import hashlib
def sha256_archivo(ruta):
resumen = hashlib.sha256()
with open(ruta, "rb") as archivo:
while bloque := archivo.read(1024 * 1024):
resumen.update(bloque)
return resumen.hexdigest()Después de restaurar una copia, vuelve a calcular el hash y compáralo antes de reemplazar información importante.
Zstd, gzip o ZIP
Elige Zstd cuando importen el rendimiento y la tasa de compresión y controles el programa lector. Elige gzip cuando necesites compatibilidad con herramientas antiguas o infraestructura web. Elige ZIP cuando quieras conservar varios nombres, directorios y metadatos en un solo contenedor. Para respaldar carpetas, también puedes crear un flujo tar y comprimirlo con Zstandard.
Escritura atómica
Escribe primero en un archivo temporal dentro del mismo sistema de archivos. Cuando termine, vacía buffers, valida el resultado y renómbralo sobre el destino. Así los demás procesos nunca observan un archivo incompleto.
from pathlib import Path
import os
final = Path("eventos.jsonl.zst")
temporal = final.with_suffix(final.suffix + ".tmp")
# Escribir y validar temporal
os.replace(temporal, final)Este patrón es especialmente valioso en tareas programadas, copias automáticas y cachés leídas de forma concurrente.
Buenas prácticas en producción
Registra bytes de entrada, bytes de salida, proporción, duración y errores. Una caída repentina en la tasa puede indicar un cambio de esquema, contenido binario inesperado o doble compresión. Define retención automática y realiza pruebas reales de restauración.
No vuelvas a comprimir JPEG, PNG, MP4, ZIP u otros formatos que ya aplican compresión. El resultado puede ser mayor y consumirá CPU. Tampoco selecciones automáticamente el nivel máximo. Un nivel intermedio suele dar una mejor relación entre coste y ahorro para pipelines continuos.
Función reutilizable
from pathlib import Path
from compression import zstd
def comprimir_archivo(origen, destino, nivel=5, bloque=1024 * 1024):
origen = Path(origen)
destino = Path(destino)
temporal = destino.with_suffix(destino.suffix + ".tmp")
try:
with origen.open("rb") as lector, temporal.open("wb") as salida:
with zstd.open(salida, mode="wb", level=nivel) as escritor:
while datos := lector.read(bloque):
escritor.write(datos)
temporal.replace(destino)
except Exception:
temporal.unlink(missing_ok=True)
raiseLa función mantiene la memoria bajo control y evita dejar un destino parcial. Puedes añadir permisos, comprobación de espacio, hashes y registros según las necesidades del proyecto.
Conclusión
compression.zstd ofrece a Python una alternativa eficiente de compresión sin pérdidas. Utiliza funciones directas para valores pequeños, streaming para archivos grandes, diccionarios para registros repetitivos y límites estrictos para contenido externo. Con hashes, métricas, pruebas de restauración y escritura atómica, Zstandard se convierte en una base fiable para backups, registros y pipelines de datos.







