{"id":498,"date":"2026-03-09T13:23:18","date_gmt":"2026-03-09T13:23:18","guid":{"rendered":"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/postgresql-performance-tuning-what-i-learned-optim\/"},"modified":"2026-03-18T22:31:23","modified_gmt":"2026-03-18T22:31:23","slug":"postgresql-performance-tuning-what-i-learned-optim","status":"publish","type":"post","link":"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/postgresql-performance-tuning-what-i-learned-optim\/","title":{"rendered":"Ajuste de Rendimiento en PostgreSQL: Lo Que Aprend\u00ed Optimizando Consultas en una Base de Datos de 10TB"},"content":{"rendered":"<p>Hace unos meses, recib\u00ed un mensaje de Slack un domingo por la tarde. El equipo de producto reportaba que el dashboard de anal\u00edticas tardaba m\u00e1s de 40 segundos en cargar. No era un caso aislado \u2014 llevaba d\u00edas as\u00ed, pero nadie lo hab\u00eda escalado. Somos un equipo de cinco personas en backend, y nuestra base <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/08\/rag-profundo-estrategias-de-chunking-bases-de-dato\/\" title=\"de Datos\">de datos<\/a> PostgreSQL (versi\u00f3n 15.3 en ese momento) hab\u00eda crecido a casi 10TB entre datos hist\u00f3ricos, logs de eventos y tablas de auditor\u00eda. <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/langchain-vs-llamaindex-vs-haystack-building-produ\/\" title=\"Lo que\">Lo que<\/a> sigui\u00f3 fueron tres semanas de investigaci\u00f3n donde aprend\u00ed m\u00e1s sobre el internals de Postgres que en los cinco a\u00f1os anteriores combinados.<\/p>\n<p>Este art\u00edculo <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/08\/benchmarks-de-asistentes-de-cdigo-ia-pruebas-de-re\/\" title=\"es lo que\">es lo que<\/a> encontr\u00e9. No es exhaustivo \u2014 hay libros enteros sobre este tema \u2014 pero son las cosas espec\u00edficas que movieron la aguja en nuestro caso.<\/p>\n<h2>El Problema Que Staging Nunca Reprodujo<\/h2>\n<p>Lo primero que hice fue correr las consultas problem\u00e1ticas <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/05\/claude-vs-gpt-4o-vs-gemini-20-qu-modelo-de-ia-usar\/\" title=\"en el\">en el<\/a> ambiente de staging. Y ah\u00ed fue donde me perd\u00ed dos d\u00edas completos.<\/p>\n<p>En staging, todo volaba. Las mismas consultas que <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/typescript-5x-in-2026-features-that-actually-matte\/\" title=\"en Producci\u00f3n\">en producci\u00f3n<\/a> tardaban 40 segundos, en staging terminaban en menos de 200ms. Obvio, \u00bfno? Staging tiene menos datos. Pero el problema m\u00e1s profundo era que staging ten\u00eda una distribuci\u00f3n <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/08\/rag-profundo-estrategias-de-chunking-bases-de-dato\/\" title=\"de Datos\">de datos<\/a> completamente distinta \u2014 no solo menos filas, sino una distribuci\u00f3n artificial que hac\u00eda que los \u00edndices se usaran de manera diferente.<\/p>\n<p>Cuando finalmente conect\u00e9 <code>pg_stat_statements<\/code> <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/typescript-5x-in-2026-features-that-actually-matte\/\" title=\"en Producci\u00f3n\">en producci\u00f3n<\/a> (deber\u00eda estar activado desde el primer d\u00eda, aprendan de m\u00ed) y empec\u00e9 a ver los query plans reales, encontr\u00e9 esto:<\/p>\n<pre><code class=\"language-sql\">-- La consulta que destru\u00eda el dashboard\nSELECT\n    u.id,\n    u.email,\n    COUNT(e.id) AS total_events,\n    MAX(e.created_at) AS last_event\nFROM users u\nLEFT JOIN events e ON e.user_id = u.id\nWHERE e.created_at &gt;= NOW() - INTERVAL '90 days'\n  AND u.organization_id = $1\nGROUP BY u.id, u.email\nORDER BY last_event DESC\nLIMIT 100;\n\n-- <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/langchain-vs-llamaindex-vs-haystack-building-produ\/\" title=\"Lo que\">Lo que<\/a> EXPLAIN ANALYZE mostraba en prod (simplificado):\n-- -&gt; Hash Join (cost=158432.00..289451.23 rows=2341 width=48)\n--      -&gt; Seq Scan on events (cost=0.00..189234.00 rows=8234123 ...)\n--           Filter: (created_at &gt;= (now() - '90 days'::interval))\n--           Rows Removed by Filter: 7,891,234\n<\/code><\/pre>\n<p>Un sequential scan sobre 8 millones de filas con casi 8 millones descartadas por el filtro. El \u00edndice en <code>events(created_at)<\/code> exist\u00eda. \u00bf<a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/redis-vs-valkey-in-2026-why-the-license-change-for\/\" title=\"Por Qu\u00e9\">Por qu\u00e9<\/a> no lo usaba?<\/p>\n<p>Pas\u00e9 medio d\u00eda asumiendo que era un problema de estad\u00edsticas desactualizadas \u2014 corr\u00ed <code>ANALYZE events<\/code> manualmente, y nada cambi\u00f3. El planner segu\u00eda eligiendo el seq scan.<\/p>\n<h2>Cuando el Planner de Postgres Tiene Raz\u00f3n y T\u00fa Est\u00e1s Equivocado<\/h2>\n<p>Ac\u00e1 est\u00e1 la cosa: el planner no estaba roto. Yo ten\u00eda un \u00edndice en <code>events(created_at)<\/code>, pero la consulta filtraba por <code>created_at<\/code> <em>y<\/em> hac\u00eda un join con <code>users<\/code> filtrando por <code>organization_id<\/code>. El \u00edndice era demasiado amplio para ser selectivo \u2014 aproximadamente el 35% de todos los eventos ca\u00edan <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/05\/claude-vs-gpt-4o-vs-gemini-20-qu-modelo-de-ia-usar\/\" title=\"en el\">en el<\/a> rango de 90 d\u00edas para organizaciones grandes. Con esa selectividad, el planner calculaba (correctamente) que era m\u00e1s barato leer la tabla entera que rebotar entre el \u00edndice y el heap.<\/p>\n<p>El fix real fue un \u00edndice compuesto <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/05\/claude-vs-gpt-4o-vs-gemini-20-qu-modelo-de-ia-usar\/\" title=\"en el\">en el<\/a> orden correcto:<\/p>\n<pre><code class=\"language-sql\">-- \u00cdndice viejo (in\u00fatil para esta consulta en datasets grandes)\nCREATE INDEX idx_events_created_at ON events(created_at);\n\n-- \u00cdndice nuevo \u2014 primero el campo de cardinalidad alta\nCREATE INDEX idx_events_user_created\n    ON events(user_id, created_at DESC)\n    WHERE created_at &gt;= '2024-01-01'; -- \u00edndice parcial\n\n-- Para la dimensi\u00f3n de organizaci\u00f3n, un \u00edndice en users ya exist\u00eda:\n-- CREATE INDEX idx_users_org ON users(organization_id);\n-- Ese s\u00ed estaba bien.\n<\/code><\/pre>\n<p>El \u00edndice parcial fue una decisi\u00f3n deliberada. Los datos de eventos de antes de 2024 pr\u00e1cticamente nunca se consultaban en tiempo real \u2014 van a reportes batch. No <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/webassembly-in-2026-where-it-actually-makes-sense\/\" title=\"Tiene Sentido\">tiene sentido<\/a> indexar datos que nunca vas a leer de forma interactiva. El \u00edndice resultante pas\u00f3 de ocupar ~80GB a ~12GB, lo cual tambi\u00e9n tiene impacto en escrituras.<\/p>\n<p>La consulta baj\u00f3 de 40 segundos a 180ms. Pero \u2014 y <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/08\/benchmarks-de-asistentes-de-cdigo-ia-pruebas-de-re\/\" title=\"esto es\">esto es<\/a> importante \u2014 eso no fue el fin del problema.<\/p>\n<h2>El Autovacuum Era el Verdadero Culpable (Tard\u00e9 Semanas en Aceptarlo)<\/h2>\n<p>Dos semanas despu\u00e9s del fix de \u00edndices, las consultas volvieron a degradarse. No tan dram\u00e1ticamente, pero suficiente para que producto se quejara de nuevo. Esta vez, 8-10 segundos. Revis\u00e9 los \u00edndices \u2014 segu\u00edan ah\u00ed, segu\u00edan siendo usados seg\u00fan <code>EXPLAIN ANALYZE<\/code>. Entonces, \u00bfqu\u00e9?<\/p>\n<p>Fui a <code>pg_stat_user_tables<\/code> y encontr\u00e9 algo que no esperaba:<\/p>\n<pre><code class=\"language-sql\">SELECT\n    relname,\n    n_dead_tup,\n    n_live_tup,\n    last_autovacuum,\n    last_autoanalyze\nFROM pg_stat_user_tables\nWHERE relname = 'events'\nORDER BY n_dead_tup DESC;\n\n-- Resultado:\n-- relname | n_dead_tup | n_live_tup | last_autovacuum        | last_autoanalyze\n-- events  | 47,234,891 | 89,123,445 | 2025-11-03 04:12:33+00 | 2025-11-03 04:13:01+00\n<\/code><\/pre>\n<p>47 millones de tuplas muertas. El autovacuum hab\u00eda corrido&#8230; hace tres semanas. En una tabla que recib\u00eda aproximadamente 500,000 inserts y updates por d\u00eda.<\/p>\n<p>El problema era la configuraci\u00f3n default de autovacuum, que est\u00e1 pensada para <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/08\/rag-profundo-estrategias-de-chunking-bases-de-dato\/\" title=\"Bases de Datos\">bases de datos<\/a> peque\u00f1as-medianas. El threshold default es 20% de la tabla \u2014 en una tabla con 89 millones de filas, eso significa que autovacuum no arranca <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/kubernetes-vs-docker-swarm-vs-nomad-container-orch\/\" title=\"Hasta Que\">hasta que<\/a> hay ~18 millones de tuplas muertas. Y cuando finalmente arranca, lo hace con recursos tan conservadores que no alcanza a limpiar todo antes de que la tabla acumule m\u00e1s bloat.<\/p>\n<p>Esto <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/08\/benchmarks-de-asistentes-de-cdigo-ia-pruebas-de-re\/\" title=\"es lo que\">es lo que<\/a> cambi\u00e9 a nivel de tabla (no toqu\u00e9 la configuraci\u00f3n global para no afectar otras tablas):<\/p>\n<pre><code class=\"language-sql\">ALTER TABLE events SET (\n    autovacuum_vacuum_scale_factor = 0.01,    -- 1% en vez de 20%\n    autovacuum_analyze_scale_factor = 0.005,  -- 0.5% para analyze\n    autovacuum_vacuum_cost_delay = 2,          -- ms, default es 20\n    autovacuum_vacuum_cost_limit = 400         -- default es 200\n);\n<\/code><\/pre>\n<p>El <code>cost_delay<\/code> y <code>cost_limit<\/code> son los que m\u00e1s impacto tuvieron. El default de 20ms de delay hace que autovacuum sea muy gentil con el I\/O \u2014 <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/webassembly-in-2026-where-it-actually-makes-sense\/\" title=\"Tiene Sentido\">tiene sentido<\/a> para que no interfiera con queries, pero en una tabla tan activa, esa gentileza se convierte en un problema de acumulaci\u00f3n. Con 2ms de delay y el doble de cost limit, autovacuum terminaba <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/05\/claude-vs-gpt-4o-vs-gemini-20-qu-modelo-de-ia-usar\/\" title=\"el Trabajo\">el trabajo<\/a> mucho m\u00e1s r\u00e1pido.<\/p>\n<p>Una cosa que no sab\u00eda antes de esto: el table bloat tambi\u00e9n afecta el query planner porque infla las estad\u00edsticas de <code>n_live_tup<\/code>, <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/langchain-vs-llamaindex-vs-haystack-building-produ\/\" title=\"Lo que\">lo que<\/a> hace que el planner sobreestime el tama\u00f1o <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/kubernetes-vs-docker-swarm-vs-nomad-comparacin-de\/\" title=\"Real de\">real de<\/a> los resultados intermedios. Los problemas de \u00edndices y autovacuum estaban interactuando de formas no obvias \u2014 arreglar solo uno daba mejoras parciales, pero no resolv\u00eda nada de ra\u00edz.<\/p>\n<h2>Configuraci\u00f3n de Memoria: Los N\u00fameros <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/kubernetes-vs-docker-swarm-vs-nomad-container-orch\/\" title=\"Que Nadie Te\">Que Nadie Te<\/a> Dice<\/h2>\n<p>Right, so \u2014 este es el apartado donde m\u00e1s me arrepiento de no haber hecho el homework desde el principio.<\/p>\n<p>Nuestra instancia era un servidor dedicado con 256GB de RAM. Y <code>shared_buffers<\/code> estaba en el default de PostgreSQL, que es 128MB. Ciento veintiocho megabytes. En un servidor con 256GB de RAM. Alguien lo hab\u00eda instalado hace a\u00f1os con la configuraci\u00f3n default y nadie lo hab\u00eda tocado. Cuando lo vi, me qued\u00e9 mirando la pantalla un momento antes de poder seguir.<\/p>\n<p>Para ser justo, no es que &#8220;poner shared_buffers alto = problema resuelto&#8221;. La relaci\u00f3n es m\u00e1s sutil. <code>shared_buffers<\/code> es la cache compartida de Postgres \u2014 pero el OS tambi\u00e9n tiene su propio page cache, y Postgres puede leer de ah\u00ed tambi\u00e9n. La recomendaci\u00f3n est\u00e1ndar de &#8220;25% de la RAM&#8221; existe por una raz\u00f3n, pero m\u00e1s no siempre es mejor porque reduce la memoria disponible para <code>work_mem<\/code>.<\/p>\n<p>Esto <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/08\/benchmarks-de-asistentes-de-cdigo-ia-pruebas-de-re\/\" title=\"es lo que\">es lo que<\/a> terminamos configurando, con el razonamiento detr\u00e1s:<\/p>\n<pre><code># postgresql.conf \u2014 nuestros valores finales para 256GB RAM\n\nshared_buffers = 64GB              # 25% de RAM\neffective_cache_size = 192GB       # estimaci\u00f3n del page cache del OS\nwork_mem = 256MB                   # por operaci\u00f3n de sort\/hash \u2014 CUIDADO con esto\nmaintenance_work_mem = 4GB         # para VACUUM, CREATE INDEX\nmax_parallel_workers_per_gather = 4\nmax_parallel_workers = 8\nrandom_page_cost = 1.1             # est\u00e1bamos en SSD NVMe, default es 4.0\n<\/code><\/pre>\n<p>El <code>random_page_cost<\/code> fue el cambio m\u00e1s sorprendente en t\u00e9rminos de impacto inmediato. El default de 4.0 le dice al planner que los random reads son 4x m\u00e1s caros que los sequential reads \u2014 lo cual era verdad en la era de los HDDs. En NVMe, la diferencia es mucho menor. Con 4.0, el planner evitaba \u00edndices y prefer\u00eda seq scans porque &#8220;parec\u00edan&#8221; m\u00e1s baratos. Bajar esto a 1.1 inmediatamente cambi\u00f3 varios planes de query.<\/p>\n<p>Con <code>work_mem<\/code> hay que ser cuidadoso. 256MB por operaci\u00f3n suena bien <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/kubernetes-vs-docker-swarm-vs-nomad-container-orch\/\" title=\"Hasta Que\">hasta que<\/a> recuerdas que <code>work_mem<\/code> se aplica <em>por operaci\u00f3n de sort\/hash<\/em>, y una consulta compleja puede tener m\u00faltiples. Con 100 conexiones concurrentes y queries con m\u00faltiples sorts, te\u00f3ricamente podr\u00edas consumir cientos de GB solo de work_mem. Nosotros monitoreamos <code>pg_stat_activity<\/code> y en la pr\u00e1ctica el uso real era mucho menor, pero el riesgo existe.<\/p>\n<p>No estoy 100% seguro de que estos valores sean los \u00f3ptimos para siempre \u2014 cuando migremos a PostgreSQL 16 (estamos en 15.6 ahora) voy a revisar si hay cambios en el planner que justifiquen ajustes. Tu millage puede variar dependiendo de tu patr\u00f3n de queries.<\/p>\n<h2>Lo Que Har\u00eda Diferente Si Empezara Desde Cero<\/h2>\n<p>Lo m\u00e1s impactante y lo m\u00e1s barato: activar <code>pg_stat_statements<\/code> desde el primer d\u00eda, con un dashboard b\u00e1sico que muestre el top 10 de queries por tiempo total <em>acumulado<\/em>. No por tiempo de ejecuci\u00f3n individual \u2014 por tiempo <em>total<\/em>, porque una query que tarda 100ms pero corre un mill\u00f3n de veces al d\u00eda es m\u00e1s da\u00f1ina que una que tarda 5 segundos pero corre dos veces por semana. Esta distinci\u00f3n me habr\u00eda ahorrado d\u00edas de investigaci\u00f3n en la direcci\u00f3n equivocada.<\/p>\n<p>Igual de importante, aunque casi siempre ignorada: revisar <code>pg_stat_user_tables<\/code> cada semana. Espec\u00edficamente <code>n_dead_tup<\/code> y <code>last_autovacuum<\/code>. Si <code>n_dead_tup<\/code> est\u00e1 creciendo consistentemente o el \u00faltimo autovacuum fue hace m\u00e1s de 24 horas en una tabla activa, algo est\u00e1 mal. Arm\u00e9 un script simple que corre cada hora y nos manda una alerta si alguna tabla supera el 10% de dead tuples relativo a live tuples. Deber\u00eda haber existido desde el d\u00eda uno.<\/p>\n<p>Sobre staging: no conf\u00edes en \u00e9l para pruebas de rendimiento a menos que tenga datos representativos en <em>distribuci\u00f3n<\/em>, no solo en volumen. <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/08\/benchmarks-de-asistentes-de-cdigo-ia-pruebas-de-re\/\" title=\"esto es\">Esto es<\/a> dif\u00edcil de mantener \u2014 lo s\u00e9 \u2014 pero el costo de no hacerlo es exactamente lo que viv\u00ed. Dos d\u00edas perdidos persiguiendo un problema que no exist\u00eda en el ambiente equivocado.<\/p>\n<p>Y si tuviera que se\u00f1alar un solo cambio arquitectural que habr\u00eda evitado la mayor parte del dolor: para tablas de eventos o logs que crecen indefinidamente, <code>pg_partman<\/code> con particionado por rango de fechas es casi siempre la respuesta correcta desde el principio. Nosotros lo estamos implementando ahora, y el proceso <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/bun-vs-nodejs-in-production-2026-real-migration-st\/\" title=\"de Migrar Una\">de migrar una<\/a> tabla monol\u00edtica de 10TB a particiones es&#8230; no divertido. Si hubiera empezado as\u00ed, el mantenimiento ser\u00eda trivial y el bloat de autovacuum ser\u00eda un problema por partici\u00f3n, no por toda la tabla.<\/p>\n<p>Los problemas de rendimiento de base <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/08\/rag-profundo-estrategias-de-chunking-bases-de-dato\/\" title=\"de Datos\">de datos<\/a> raramente tienen una causa \u00fanica \u2014 eso fue quiz\u00e1s la lecci\u00f3n m\u00e1s dura de aceptar. Lo que yo ten\u00eda era un \u00edndice sub\u00f3ptimo m\u00e1s un autovacuum desconfigurado m\u00e1s par\u00e1metros de memoria default en hardware moderno, cada uno contribuyendo al problema a su manera. Ver el sistema completo, no solo la query lenta, <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/08\/benchmarks-de-asistentes-de-cdigo-ia-pruebas-de-re\/\" title=\"es lo que\">es lo que<\/a> finalmente lo resolvi\u00f3.<\/p>\n<p>Mi recomendaci\u00f3n concreta si est\u00e1s en una situaci\u00f3n similar: antes de crear cualquier \u00edndice o cambiar cualquier configuraci\u00f3n, dedica un d\u00eda entero solo a observar. Activa <code>pg_stat_statements<\/code>, deja correr por 24 horas, y construye un cuadro completo de qu\u00e9 queries consumen m\u00e1s recursos y cu\u00e1l es el estado <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/kubernetes-vs-docker-swarm-vs-nomad-comparacin-de\/\" title=\"Real de\">real de<\/a> tus tablas. El tiempo de diagn\u00f3stico honesto es la mejor inversi\u00f3n que puedes hacer.<\/p>\n<p><!-- Reviewed: 2026-03-09 | Status: ready_to_publish | Changes: broke Primero\/Segundo\/Tercero\/Cuarto parallel structure in last section, added personality beat on discovering 128MB shared_buffers, tightened autovacuum section conclusion, fixed \"Obvious\" \u2192 \"Obvio\", minor flow improvements throughout --><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hace unos meses, recib\u00ed un mensaje de Slack un domingo por la tarde.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[1],"tags":[],"class_list":["post-498","post","type-post","status-publish","format-standard","hentry","category-general"],"_links":{"self":[{"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/posts\/498","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/comments?post=498"}],"version-history":[{"count":11,"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/posts\/498\/revisions"}],"predecessor-version":[{"id":771,"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/posts\/498\/revisions\/771"}],"wp:attachment":[{"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/media?parent=498"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/categories?post=498"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/tags?post=498"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}