[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"doc-seo-672880-105":3,"detail-sidebar-cat-0-en-105":83,"doc-detail-672880-en":133},{"code":4,"msg":5,"data":6},0,"ok",{"site_id":7,"language":8,"slug":9,"title":10,"keywords":11,"description":12,"schema_data":13,"social_meta":76,"head_meta":78,"extra_data":80,"updated_unix":82},105,"en","designing-domain-oriented-dbt-projects-and-making-them-work-in-airflow-talk","Designing domain-oriented dbt projects and making them work in Airflow - Talk","","A talk titled “Designing domain-oriented dbt projects and making them work in Airflow” explains why large dbt monolith repositories stop scaling when teams and models grow. It contrasts slow feedback, increasing CI parsing time, blast-radius failures, blurred ownership, and merge friction in a single-project setup with a dbt Mesh approach. The talk covers domain project splitting, public interfaces with access controls, contracts and versions, and cross-project refs orchestrated by Cosmos and Airflow.",{"@graph":14,"@context":75},[15,34,54],{"@type":16,"itemListElement":17},"BreadcrumbList",[18,23,27,31],{"item":19,"name":20,"@type":21,"position":22},"https://docshare.wps.com","Home","ListItem",1,{"item":24,"name":25,"@type":21,"position":26},"https://docshare.wps.com/document/","Document",2,{"item":28,"name":29,"@type":21,"position":30},"https://docshare.wps.com/document/technology/","Technology",3,{"item":32,"name":10,"@type":21,"position":33},"https://docshare.wps.com/document/designing-domain-oriented-dbt-projects-and-making-them-work-in-airflow-talk/672880/",4,{"url":32,"name":10,"@type":35,"image":36,"author":41,"headline":10,"publisher":44,"fileFormat":47,"inLanguage":8,"description":12,"dateModified":48,"datePublished":48,"encodingFormat":47,"isAccessibleForFree":49,"interactionStatistic":50},"DigitalDocument",{"url":37,"@type":38,"width":39,"height":40},"https://docshare.wps.com/thumbnails/designing-domain-oriented-dbt-projects-and-making-them-work-in-airflow-talk/672880.png","ImageObject",300,407,{"name":42,"@type":43},"Mary Man","Person",{"url":19,"name":45,"@type":46},"DocShare","Organization","application/pdf","2026-11-02",true,{"@type":51,"interactionType":52,"userInteractionCount":22},"InteractionCounter",{"@type":53},"ViewAction",{"@type":55,"mainEntity":56},"FAQPage",[57,63,67,71],{"name":58,"@type":59,"acceptedAnswer":60},"Why does a dbt monolith stop scaling when models reach around 2,000?","Question",{"text":61,"@type":62},"The talk highlights slow feedback as feedback cycles wait on the whole graph, growing CI parsing time for every change, and a larger blast radius where one broken staging model can stall marts. It also notes blurred ownership and merge friction due to many engineers sharing one repo and YAML.","Answer",{"name":64,"@type":59,"acceptedAnswer":65},"What is the core design change proposed in dbt Mesh?",{"text":66,"@type":62},"Split the monolith into domain projects, applying data-mesh ideas to dbt. Each business domain gets its own dbt project owned by the team that lives in that data, with bounded contexts and clear edges.",{"name":68,"@type":59,"acceptedAnswer":69},"How do teams prevent breaking downstream consumers when a public model changes?",{"text":70,"@type":62},"Use contracts and versions. Contracts pin public column names and data types and fail builds if the shape drifts, while versions let producers ship v2 while v1 continues to serve existing consumers so consumers migrate on their own schedule.",{"name":72,"@type":59,"acceptedAnswer":73},"How are domain projects connected without copying shared logic?",{"text":74,"@type":62},"Declare upstream projects in dependencies.yml and use ref('project','model') in SQL. The talk emphasizes one definition and one owner, using cross-project ref as the seam between projects.","https://schema.org",{"og:url":32,"og:type":77,"og:title":10,"og:site_name":45,"og:description":12},"article",{"robots":79,"canonical":32},"index,follow",{"doc_id":81,"site_id":7},672880,1793611872,{"code":4,"msg":84,"data":85},"success",[86,90,94,98,103,107,112,117,122,125,129],{"id":22,"doc_module":4,"doc_module_name":25,"category_name":87,"show_sort_weight":88,"slug":89},"Story & Novel",90,"story-novel",{"id":26,"doc_module":4,"doc_module_name":25,"category_name":91,"show_sort_weight":92,"slug":93},"Literature",80,"literature",{"id":33,"doc_module":4,"doc_module_name":25,"category_name":95,"show_sort_weight":96,"slug":97},"Exam",70,"exam",{"id":99,"doc_module":4,"doc_module_name":25,"category_name":100,"show_sort_weight":101,"slug":102},5,"Comic",60,"comic",{"id":104,"doc_module":4,"doc_module_name":25,"category_name":29,"show_sort_weight":105,"slug":106},6,50,"technology",{"id":108,"doc_module":4,"doc_module_name":25,"category_name":109,"show_sort_weight":110,"slug":111},7,"Healthcare",40,"healthcare",{"id":113,"doc_module":4,"doc_module_name":25,"category_name":114,"show_sort_weight":115,"slug":116},8,"Research & Report",30,"research-report",{"id":118,"doc_module":4,"doc_module_name":25,"category_name":119,"show_sort_weight":120,"slug":121},9,"Religion & Spirituality",20,"religion-spirituality",{"id":120,"doc_module":4,"doc_module_name":25,"category_name":123,"show_sort_weight":120,"slug":124},"World Cup","world-cup",{"id":126,"doc_module":4,"doc_module_name":25,"category_name":127,"show_sort_weight":126,"slug":128},10,"Lifestyle","lifestyle",{"id":130,"doc_module":4,"doc_module_name":25,"category_name":131,"show_sort_weight":99,"slug":132},19,"General","general",{"code":4,"msg":84,"data":134},{"doc_id":81,"user_id":135,"nickname":42,"user_avatar":136,"doc_module":4,"category_id":104,"category_name":29,"doc_title":10,"doc_description":12,"doc_content":137,"file_id":138,"file_url":139,"file_type":140,"file_size":141,"view_count":22,"is_deleted":4,"is_public":22,"is_downloadable":22,"audit_status":22,"page_count":142,"language":143,"language_code":8,"site_id":7,"html_lang":8,"table_of_contents":144,"faqs":145,"seo_title":146,"seo_description":12,"update_tm":82,"read_time":147},7421720224475,"https://ap-avatar.wpscdn.com/davatar_276721f389ce27ea32af1340a28f341c","AIRFLOW SUMMIT 2026  \nDesigning domain-oriented dbt projects and making them  \nwork in Airﬂow  \nPankaj Koti Senior Software Engineer, Astronomer · Apache Airﬂow Committer & Cosmos maintainer  \nTHE STORY IN ONE LINE  \nYour dbt project started at 20 models.  \nToday it is 2,000, and every team blocks every other team.  \n01  \nThe problem  \nOne monolith, many teams, why it stops scaling  \n02  \nThe design  \ndbt Mesh: split into domain projects with clean interfaces  \n03  \nMake it run  \nCosmos + Airﬂow orchestrate the pieces  \nACT 1 · THE PROBLEM  \nOne project. Every team. Every model.  \n● A single dbt_project.yml that ﬁnance, marketing, product and platform all commit to  \n● One `dbt run` builds the whole graph, staging, marts, everything, together  \n● It felt great at 50 models. It does not feel great at 2,000  \n03 / 30  \nACT 1 · THE PROBLEM  \nHow the monolith actually hurts  \nSlow feedback  \nParsing and CI grow with the whole graph, every change waits on everything  \nBlast radius  \nOne broken staging model can stall marts for teams that never touched it  \nBlurred ownership  \nWho owns this model? The whole company can edit it, so no one is accountable  \nMerge friction  \nDozens of engineers, one repo, one YAML, constant conﬂicts  \n04 / 30  \nACT 1 · THE DESIGN  \nThe ﬁx: split by domain  \nData mesh, applied to dbt. Give each business domain its own dbt project, owned by the team that lives in that data.  \n● Platform owns shared, foundational models  \n● Finance, Marketing, Product own their own marts  \n● Bounded contexts, clear edges, clear owners  \nmonolith  \n→  \n05 / 30  \nACT 1 · THE DESIGN  \nA domain project has a public interface  \n● Owned by one team, in its own directory or repo  \n● Exposes a small, deliberate set of public models, its API  \n● Everything else stays private, free to refactor without breaking others  \n● Other domains depend on the interface, not the internals  \nplatform project  \nprivate (staging, intermediate)  \n+access: public → the interface  \nﬁnance / marketing consume only the public models  \n06 / 30  \nACT 1 · THE DESIGN  \ndbt Mesh is the toolbox for this  \naccess  \npublic / protected / private, deﬁne the interface  \nversions  \nevolve a model while old consumers still work  \ncontracts  \npin column names & types so consumers don't break  \ngroups  \nassign ownership to a team  \ncross-project ref  \nreference another project's model by name  \nCosmos leans on access and cross-project ref the most, that is the seam between projects.  \n07 / 30  \nACT 1 · THE DESIGN  \nThe interface: +access: public  \n● Only public models can be referenced from another project  \n● private (default) and protected stay inside the domain  \n● This one line turns a model into a contract-bearing API surface  \nupstream/dbt_project.yml  \nmodels:  \nupstream:  \nstaging:  \n+materialized: view  \n+access: public \\# expose to others  \nintermediate:  \n+materialized: view  \n+access: public  \n\\# everything else stays private  \n08 / 30  \nACT 1 · THE DESIGN  \nGoverned change: contracts & versions  \nContracts  \nPin the column names and data types a public model promises.  \nA pre-ﬂight check fails the build if the shape drifts, so a producer can't silently break a downstream consumer.  \nVersions  \nShip v2 of a model while v1 still serves existing consumers.  \nConsumers migrate on their own schedule, coordinated change instead of a ﬂag day.  \n09 / 30  \nACT 1 · THE DESIGN  \nThe seam: reference, don't copy  \n● Declare the upstream project in dependencies.yml  \n● Then use ref('project', 'model') in your SQL  \n● One deﬁnition, one owner, no copy-paste of shared logic  \ndownstream/dependencies.yml  \nprojects:  \n- name: upstream  \ndownstream/models/fct_ revenue.sql  \nselect * from  \n{{ ref('upstream', 'int_orders_enriched') }} where status = 'completed'  \n10 / 30","cbCaiijOVYQvlWse","https://ap.wps.com/l/cbCaiijOVYQvlWse","pdf",2924343,31,"English","# The problem\n## One monolith, many teams, why it stops scaling\n## How the monolith actually hurts\n# The design\n## dbt Mesh: split into domain projects with clean interfaces\n## The interface: +access: public\n## Governed change: contracts & versions\n## The seam: reference, don't copy\n# Make it run\n## Cosmos + Airflow orchestrate the pieces","[{\"question\":\"Why does a dbt monolith stop scaling when models reach around 2,000?\",\"answer\":\"The talk highlights slow feedback as feedback cycles wait on the whole graph, growing CI parsing time for every change, and a larger blast radius where one broken staging model can stall marts. It also notes blurred ownership and merge friction due to many engineers sharing one repo and YAML.\"},{\"question\":\"What is the core design change proposed in dbt Mesh?\",\"answer\":\"Split the monolith into domain projects, applying data-mesh ideas to dbt. Each business domain gets its own dbt project owned by the team that lives in that data, with bounded contexts and clear edges.\"},{\"question\":\"How do teams prevent breaking downstream consumers when a public model changes?\",\"answer\":\"Use contracts and versions. Contracts pin public column names and data types and fail builds if the shape drifts, while versions let producers ship v2 while v1 continues to serve existing consumers so consumers migrate on their own schedule.\"},{\"question\":\"How are domain projects connected without copying shared logic?\",\"answer\":\"Declare upstream projects in dependencies.yml and use ref('project','model') in SQL. The talk emphasizes one definition and one owner, using cross-project ref as the seam between projects.\"}]","Designing domain-oriented dbt projects and making them work in Airflow - Talk | PDF",78]