El módulo compression.zstd incorpora soporte para Zstandard en la biblioteca estándar de Python. Zstandard, conocido como Zstd, fue diseñado para ofrecer una relación muy equilibrada entre velocidad y tasa de compresión. Resulta útil en APIs, pipelines de datos, copias de seguridad, archivos de logs, cachés, distribución de artefactos y comunicación entre servicios. En lugar de elegir solamente entre compresión rápida o archivos pequeños, Zstd permite ajustar el nivel según las necesidades de cada flujo.
Esta guía explica cómo comprimir y descomprimir bytes, procesar archivos grandes mediante streaming, aplicar límites de seguridad, usar diccionarios y organizar un flujo preparado para producción. El objetivo no es mostrar únicamente llamadas de API, sino también las decisiones que evitan consumo excesivo de memoria, salidas corruptas, cargas peligrosas e integraciones difíciles de mantener.
Por qué usar Zstandard
Los algoritmos tradicionales siguen siendo útiles, pero cada formato tiene ventajas y costes diferentes. Gzip posee una compatibilidad muy amplia, mientras que LZMA suele producir archivos menores con un gasto de CPU más elevado. Zstandard ocupa un punto práctico: comprime rápido, descomprime todavía más rápido y ofrece numerosos niveles. Esto ayuda a procesar grandes volúmenes sin aumentar demasiado la latencia.
El formato también admite diccionarios de compresión, especialmente útiles cuando muchos documentos pequeños comparten estructuras. Mensajes JSON, eventos de telemetría y registros con nombres de campos repetidos pueden obtener mejores resultados. Antes de adoptar el formato, confirma que los demás sistemas pueden leer Zstd y documenta la versión mínima de Python.
Compresión básica en memoria
Para bloques pequeños, el enfoque más sencillo trabaja con bytes. Convierte las cadenas usando una codificación explícita, comprime el resultado y, al leer, descomprime y decodifica con la misma codificación.
from compression import zstd
texto = "datos repetidos " * 1000
originales = texto.encode("utf-8")
comprimidos = zstd.compress(originales)
restaurados = zstd.decompress(comprimidos)
assert restaurados == originales
print(len(originales), len(comprimidos))Este patrón es apropiado cuando el contenido completo cabe cómodamente en memoria. No cargues de una sola vez un backup de varios gigabytes ni un upload no confiable. En esos casos, utiliza streaming para mantener un consumo predecible.
Niveles de compresión
El nivel controla el equilibrio entre tiempo de CPU y tamaño final. Los niveles bajos funcionan bien para respuestas de API y pipelines en tiempo real. Los niveles altos pueden ser razonables para artefactos descargados muchas veces o guardados durante largos periodos. El valor ideal depende de los datos reales, por lo que conviene medir con muestras representativas.
comprimidos = zstd.compress(originales, level=6)No selecciones el nivel máximo solo porque produce un archivo ligeramente menor. El coste extra puede no compensar. Mide tiempo de compresión, tiempo de descompresión, tamaño y efecto sobre el sistema. En muchos proyectos, un nivel intermedio ofrece el mejor resultado operativo.
Archivos grandes con streaming
El streaming lee y escribe por bloques. Esto reduce picos de memoria y permite trabajar con archivos mayores que la RAM disponible. Abre los archivos en modo binario y utiliza bloques razonables.
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") as compresor:
while bloque := entrada.read(1024 * 1024):
compresor.write(bloque)Durante la descompresión, escribe primero en un archivo temporal y reemplaza el destino definitivo únicamente al finalizar. Así evitas que una interrupción, una entrada inválida o un disco lleno deje un archivo parcial bajo el nombre esperado.
temporal = Path("eventos.jsonl.tmp")
with destino.open("rb") as entrada, zstd.open(entrada, mode="rb") as lector:
with temporal.open("wb") as salida:
while bloque := lector.read(1024 * 1024):
salida.write(bloque)
temporal.replace(origen)Protección contra bombas de descompresión
Un archivo pequeño puede expandirse hasta ocupar mucho espacio. Cuando la entrada no es confiable, limita la cantidad de bytes producidos. Comprobar únicamente el tamaño comprimido no es suficiente. Cuenta los bytes descomprimidos e interrumpe la operación al superar el máximo permitido.
limite = 500 * 1024 * 1024
total = 0
with zstd.open("entrada.zst", mode="rb") as lector:
with open("salida.tmp", "wb") as salida:
while bloque := lector.read(1024 * 1024):
total += len(bloque)
if total > limite:
raise ValueError("el contenido supera el límite")
salida.write(bloque)Aplica además timeouts, límites de CPU, cuotas de disco y validación del formato esperado. Los servicios web deberían procesar uploads en directorios aislados y no confiar en el nombre proporcionado por el usuario.
Integridad y archivos dañados
Gestiona los errores de lectura de forma explícita. Captura excepciones específicas, elimina temporales y registra contexto suficiente para diagnosticar. Nunca reemplaces un archivo válido antes de confirmar que la descompresión terminó correctamente.
Para distribuir artefactos, publica también un hash criptográfico, como SHA-256. La compresión reduce tamaño, pero no autentica el origen. Usa firmas digitales o un canal confiable cuando la autenticidad sea importante.
Diccionarios de compresión
Los diccionarios mejoran resultados cuando muchos documentos pequeños comparten patrones. Se entrenan con muestras representativas y deben estar disponibles tanto al comprimir como al descomprimir. Asigna un identificador y una versión a cada diccionario. Utilizar el diccionario incorrecto debe considerarse un error.
No entrenes un diccionario público con datos secretos. Evalúa también la complejidad operativa: almacenar, versionar y seleccionar diccionarios añade trabajo. Conserva esta técnica solo cuando los benchmarks demuestren un beneficio claro.
Metadatos y versiones de esquema
Un archivo .zst contiene bytes comprimidos, pero la aplicación aún necesita conocer el tipo de contenido, la versión del esquema, la codificación, el tamaño esperado y el identificador del diccionario. Guarda esta información en un manifiesto o en un encabezado propio.
Cuando cambie el formato lógico, mantén lectores compatibles o proporciona una migración. La compresión no sustituye el versionado del esquema.
Uso en APIs
En HTTP, negocia soporte antes de devolver contenido Zstd. Configura correctamente encabezados, cachés y proxies. Para payloads muy pequeños, la compresión puede gastar más CPU de la que ahorra en red. Define un tamaño mínimo y monitoriza ratio y latencia.
No vuelvas a comprimir formatos ya comprimidos, como JPEG, MP4 y muchos PDF. El ahorro suele ser pequeño y el coste innecesario.
Concurrencia y colas
La compresión consume CPU. En aplicaciones asíncronas, evita bloquear el event loop con archivos grandes. Envía el trabajo a un thread, proceso o worker. Limita la concurrencia para impedir que varias tareas agoten CPU, memoria o disco.
Registra bytes de entrada, bytes de salida, duración, nivel y fallos. Estas métricas permiten ajustar la configuración y detectar regresiones.
Pruebas esenciales
Prueba contenido vacío, payloads pequeños, archivos grandes, entradas truncadas, formatos inválidos y límites de expansión. Realiza pruebas de ida y vuelta para confirmar que los bytes restaurados coinciden exactamente con los originales. Incluye texto Unicode, datos binarios y varios tamaños de bloque.
Prueba también errores de disco e interrupciones. El destino original debe permanecer intacto. En sistemas críticos, crea temporales en el mismo sistema de archivos para que el reemplazo final sea atómico.
Buenas prácticas
- Usa bytes y modos binarios.
- Prefiere streaming para datos grandes.
- Aplica límites de expansión y disco.
- Mide niveles con datos reales.
- Versiona diccionarios y esquemas.
- Escribe primero en archivos temporales.
- Usa hashes o firmas para integridad y autenticidad.
- Monitoriza CPU, duración y tasa de compresión.
Continúa con las guías de Academify sobre pathlib en Python, hashlib en Python, JSON en Python y asyncio en Python.
Conclusión
El módulo compression.zstd ofrece una opción moderna para comprimir datos con velocidad y eficiencia. Las funciones básicas resuelven bloques pequeños, mientras que streaming, límites, temporales, metadatos versionados y métricas convierten el flujo en una solución apta para producción. El mayor beneficio aparece al tratar la compresión como un proceso completo: validar entradas, proteger recursos, probar restauración, documentar compatibilidad y medir resultados.







