{"id":16162,"date":"2023-12-01T06:00:00","date_gmt":"2023-12-01T06:00:00","guid":{"rendered":"https:\/\/www.directimpactsolutions.com\/?p=16162"},"modified":"2025-05-01T03:06:46","modified_gmt":"2025-05-01T03:06:46","slug":"new-flush-option-loop-script-step","status":"publish","type":"post","link":"https:\/\/www.directimpactsolutions.com\/en\/new-flush-option-loop-script-step\/","title":{"rendered":"New Flush Option for FileMaker&#8217;s Loop Script Step"},"content":{"rendered":"<p>According to Claris&#8217; <a href=\"https:\/\/help.claris.com\/en\/pro-release-notes\/content\/index.html\" target=\"_blank\" rel=\"noreferrer noopener\">FileMaker Pro Release Notes for Version 20.3.1<\/a>,<\/p><blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>Flush includes the following three values:<br>1. Always: When setting a field within a loop, the relationship is flushed along with the join data.<br>2. Minimum: When setting a field within a loop, minimal data is flushed.<br>3. Defer: When setting a field within a loop, data and relationship data are flushed only after exiting the loop.<\/p><\/blockquote><p>What does that mean, and how does it impact your FileMaker solutions?<\/p><div class=\"wp-block-uagb-image uagb-block-57ea04ef wp-block-uagb-image--layout-default wp-block-uagb-image--effect-static wp-block-uagb-image--align-none\"><figure class=\"wp-block-uagb-image__figure\"><img decoding=\"async\"  sizes=\"auto, (max-width: 480px) 150px\" src=\"https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/11\/flush-option.png\" alt=\"\" width=\"242\" height=\"119\" title=\"\" loading=\"lazy\" role=\"img\"\/><\/figure><\/div><p>The new <strong>flush<\/strong> option for the loop script step<\/p><h2 class=\"wp-block-heading\" style=\"font-style:normal;font-weight:400\">Understanding Relationships and Join Data<\/h2><p>We can use relationships to fetch and display data from related tables.<\/p><p>In this scenario, consider the relationship as a tunnel going from the current record in the current table to the related table, helping us locate related records.<\/p><p>Whenever a relationship is established, FileMaker will use the relationship to identify related records, query related data, and cache the queried result. These cached related records&#8217; data are referred to as <em>join data<\/em>.<\/p><p>If we update the value of one of the fields used on the left side of the relationship, typically, FileMaker will need to re-establish the relationship (find related records again) and re-query the join data (fetch related records&#8217; data via the relationship again).<\/p><p>For example, I have a relationship shown in the screenshot below. It is used to display a list of related records in a portal. On the left side of the relationship, I use a global field zgtProjectCategoryFilter, to show only related records with a matching project category.<\/p><div class=\"wp-block-uagb-image uagb-block-1aa4e22c wp-block-uagb-image--layout-default wp-block-uagb-image--effect-static wp-block-uagb-image--align-none\"><figure class=\"wp-block-uagb-image__figure\"><img decoding=\"async\" srcset=\"https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/11\/relationship.png ,https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/11\/relationship.png 780w, https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/11\/relationship.png 360w\" sizes=\"auto, (max-width: 480px) 150px\" src=\"https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/11\/relationship.png\" alt=\"\" class=\"uag-image-16166\" width=\"830\" height=\"626\" title=\"\" loading=\"lazy\" role=\"img\"\/><\/figure><\/div><p>A relationship used for a filterable portal<\/p><p>On the layout, the user can set the value of zgtProjectCategoryFilter to one of the three values using these buttons:<\/p><figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"318\" height=\"78\" src=\"https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/11\/buttons.png\" alt=\"\" class=\"wp-image-16169\" srcset=\"https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/11\/buttons.png 318w, https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/11\/buttons-300x74.png 300w\" sizes=\"auto, (max-width: 318px) 100vw, 318px\" \/><\/figure><p>Whenever a user changes the value, FileMaker will need to flush the cached join data, re-establish the relationship and re-query the join data so the portal displayed on the layout can achieve the \u201cfiltering\u201d effect.<\/p><h2 class=\"wp-block-heading\" style=\"font-style:normal;font-weight:400\">Performance Implication<\/h2><p>Now that we understand relationships and join data, what are the implications of the new flush option?<\/p><p>Imagine you have a script that loops. Each time it loops, it updates a field on the left side of a relationship. Imagine this field is used in multiple relationships, and a large amount of join data might be fetched through those relationships. By default, FileMaker will flush and re-query every time the left side field is updated. This could have a serious performance implication for your solution, especially if it runs over the WAN (check out <a href=\"https:\/\/youtu.be\/FrrNzlxgbHU?si=4vVOCBso0M3ou_ew\" target=\"_blank\" rel=\"noreferrer noopener\">this video<\/a> to understand why).<\/p><p>Before version 20.3.1, we had some, but limited, control over when FileMaker flushed the join data (with the Refresh Window script step), but not when it comes to looping that sets fields used in relationships. Under the loop scenario, FileMaker will always flush and re-query, regardless of necessity.<\/p><p>With Version 20.3.1, this new feature gives developers control over when FileMaker should re-establish the relationship and flush join data. It allows us to avoid expensive flush operations when unnecessary.<\/p><p>Let\u2019s take a second look at the release notes\u2014this time, you should have a bit more context:<\/p><blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>Flush includes the following three values:<br>1. Always: When setting a field within a loop, the relationship is flushed along with the join data.<br>2. Minimum: When setting a field within a loop, minimal data is flushed.<br>3. Defer: When setting a field within a loop, data and relationship data are flushed only after exiting the loop.<\/p><\/blockquote><p><em>Always<\/em> is what we had before this version, and it is the default option. If you open up a FileMaker solution using FileMaker Pro version 20.3.1+ for the first time, all of your loop flush options will be set to <em>Always<\/em>. This flushes not when it\u2019s necessary, but when it can.<\/p><p><em>Defer<\/em> is fast. Its behavior is simple: it will try not to flush anything until exiting the loop. There will be one flush, in total, at the end.<\/p><p><em>Minimum<\/em> is a bit mysterious. At the time of this article\u2019s publication, there\u2019s no official documentation on this feature other than what\u2019s quoted above. The name seems to indicate that this option is doing something smart to minimize the amount of join data flushed while looping. Based on my testing, my guess is that its behavior is between <em>Always<\/em> and <em>Defer<\/em>; <em>Minimum<\/em> tries to do as few flushes as possible, unless other script steps in the loop require a flush.<\/p><h2 class=\"wp-block-heading\" style=\"font-style:normal;font-weight:400\">Behavior and Performance Tests<\/h2><h3 class=\"wp-block-heading has-ast-global-color-2-color has-text-color\">Testing Method<\/h3><p>To test this feature, I used a scenario like what I described above: one field that is part of nine different relationships gets updated repeatedly.<\/p><p>In the earlier example, I only showed one relationship with the global field. In reality, I have nine of them.<\/p><div class=\"wp-block-uagb-image uagb-block-408afd79 wp-block-uagb-image--layout-default wp-block-uagb-image--effect-static wp-block-uagb-image--align-none\"><figure class=\"wp-block-uagb-image__figure\"><img decoding=\"async\" srcset=\"https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/11\/nine-relationships.png ,https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/11\/nine-relationships.png 780w, https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/11\/nine-relationships.png 360w\" sizes=\"auto, (max-width: 480px) 150px\" src=\"https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/11\/nine-relationships.png\" alt=\"\" class=\"uag-image-16172\" width=\"433\" height=\"510\" title=\"\" loading=\"lazy\" role=\"img\"\/><\/figure><\/div><p>Nine relationships that use the zgtProjectCategoryFIlter field on the left side<\/p><p>This is probably not the smartest way for me to build a grid view in FileMaker, but it\u2019s perfect for testing out this new feature.<\/p><p>The testing script I used is shown in the screenshot below. It runs from a layout that uses these relationships to display related data in portals. The script loops many times, and each time it loops, it sets the zgtProjectCategoryFilter field to a different value; in the end, it spits out the total time taken, and a list of related data fetched.<\/p><details class=\"wp-block-details is-layout-flow wp-block-details-is-layout-flow\"><summary>Testing Process and Data<\/summary><h3 class=\"wp-block-heading has-ast-global-color-2-color has-text-color\">Test Case 1 &#8211; 999 loops, fetch join data mid-loop &amp; evaluate portals<\/h3>\n\n<p>For the first test, inside each loop, I tried to fetch one piece of join data and record it.<\/p>\n\n<div class=\"wp-block-uagb-image uagb-block-5bf38036 wp-block-uagb-image--layout-default wp-block-uagb-image--effect-static wp-block-uagb-image--align-none\"><figure class=\"wp-block-uagb-image__figure\"><img decoding=\"async\" srcset=\"https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/11\/test-case-1.png ,https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/11\/test-case-1.png 780w, https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/11\/test-case-1.png 360w\" sizes=\"auto, (max-width: 480px) 150px\" src=\"https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/11\/test-case-1.png\" alt=\"\" class=\"uag-image-16175\" width=\"730\" height=\"158\" title=\"\" loading=\"lazy\" role=\"img\"\/><\/figure><\/div>\n\n<p>Script used<\/p>\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><\/td><td><strong>Testing Scenario<\/strong><\/td><td><strong>Always<\/strong><\/td><td><strong>Minimum<\/strong><\/td><td><strong>Defer<\/strong><\/td><\/tr><tr><td><strong>1<\/strong><\/td><td>999 loops<br>9 relationships<br>23 related records at most<br>2023-11-26<\/td><td>22 seconds<br>Mid-loop data fetched is accurate<\/td><td>18 seconds<br>Mid-loop data fetched is accurate<\/td><td>1 seconds<br>Mid-loop data fetched is NOT accurate<\/td><\/tr><tr><td><strong>2<\/strong><\/td><td>999 loops<br>9 relationships<br>13 related records at most<br>2023-12-10<\/td><td>21 seconds<br>Mid-loop data fetched is accurate<\/td><td>18 seconds<br>Mid-loop data fetched is accurate<\/td><td>~0 seconds<br>Mid-loop data fetched is NOT accurate<\/td><\/tr><tr><td><strong>3<\/strong><\/td><td>999 loops<br>5 relationships<br>13 related records<br>2023-12-24<\/td><td>21 seconds<br>Mid-loop data fetched is accurate<\/td><td>18 seconds<br>Mid-loop data fetched is accurate<\/td><td>~0 seconds<br>Mid-loop data fetched is NOT accurate<\/td><\/tr><\/tbody><\/table><\/figure>\n\n<h3 class=\"wp-block-heading has-ast-global-color-2-color has-text-color\" id=\"Test-Case-2---999-loops,-only-evaluate-portals\">Test Case 2 &#8211; 999 loops, only evaluate portals<\/h3>\n\n<p>Now, let me disable the step that fetches the related data in the middle of the loop, leaving only the layout utilizing join data.<\/p>\n\n<div class=\"wp-block-uagb-image uagb-block-c322bdac wp-block-uagb-image--layout-default wp-block-uagb-image--effect-static wp-block-uagb-image--align-none\"><figure class=\"wp-block-uagb-image__figure\"><img decoding=\"async\"  sizes=\"auto, (max-width: 480px) 150px\" src=\"https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/11\/script-used.png\" alt=\"\" width=\"730\" height=\"156\" title=\"\" loading=\"lazy\" role=\"img\"\/><\/figure><\/div>\n\n<p>Script used<\/p>\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><\/td><td><strong>Testing Scenario<\/strong><\/td><td><strong>Always<\/strong><\/td><td><strong>Minimum<\/strong><\/td><td><strong>Defer<\/strong><\/td><\/tr><tr><td><strong>1<\/strong><\/td><td>999 loops<br>9 relationships<br>23 related records at most<\/td><td>1 seconds<\/td><td>~0 seconds<\/td><td>~0 seconds<\/td><\/tr><tr><td><strong>2<\/strong><\/td><td>999 loops<br>9 relationships<br>13 related records at most<\/td><td>~0 seconds<\/td><td>~0 seconds<\/td><td>~0 seconds<\/td><\/tr><tr><td><strong>3<\/strong><\/td><td>999 loops<br>5 relationships<br>13 related records<\/td><td>~0 seconds<\/td><td>~0 seconds<\/td><td>~0 seconds<\/td><\/tr><\/tbody><\/table><\/figure>\n\n<h3 class=\"wp-block-heading has-ast-global-color-2-color has-text-color\" id=\"Test-Case-3---99,900-loops,-only-evaluate-portals\">Test Case 3 &#8211; 99,900 loops, only evaluate portals<\/h3>\n\n<p>To test the overhead introduced by layouts during loops, I cranked up the total loop count by a hundredfold to 99,900.<\/p>\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><\/td><td><strong>Testing Scenario<\/strong><\/td><td><strong>Always<\/strong><\/td><td><strong>Minimum<\/strong><\/td><td><strong>Defer<\/strong><\/td><\/tr><tr><td><strong>1<\/strong><\/td><td>99,900 loops<br>9 relationships<br>23 related records at most<\/td><td>50 seconds<\/td><td>10 seconds<\/td><td>8 seconds<\/td><\/tr><tr><td><strong>2<\/strong><\/td><td>99,900 loops<br>9 relationships<br>13 related records at most<\/td><td>49 seconds<\/td><td>9 seconds<\/td><td>9 seconds<\/td><\/tr><tr><td><strong>3<\/strong><\/td><td>99900 loops<br>5 relationships<br>13 related records<\/td><td>47 seconds<\/td><td>9 seconds<\/td><td>9 seconds<\/td><\/tr><\/tbody><\/table><\/figure>\n\n<h3 class=\"wp-block-heading has-ast-global-color-2-color has-text-color\" id=\"Bonus-Test-Case---99,900-loops,-only-evaluate-portals-&amp;-data-viewer-accidentally-left-open-with-\u201cautomatically-evaluate\u201d-on\">Bonus Test Case &#8211; 99,900 loops, only evaluate portals &amp; data viewer accidentally left open with \u201cautomatically evaluate\u201d on<\/h3>\n\n<p>Accidentally leaving the data viewer open significantly slowed down the process. Even though I\u2019m not using it to watch any join data relevant to my test.<\/p><\/details><p><\/p><h2 class=\"wp-block-heading\" style=\"font-style:normal;font-weight:400\">Conclusions &amp; Usage Considerations<\/h2><ol start=\"1\" class=\"wp-block-list\"><li>The <em>Defer<\/em> option does not flush join data in the middle of the loop at all. This is why, in test case 1, the mid-loop join data fetched with the <em>Defer<\/em> option is inaccurate.<ol start=\"1\" class=\"wp-block-list\"><li>This verifies the behavior mentioned in the release notes.<\/li>\n\n<li>This also explains why it\u2019s the fastest among the three options.<\/li>\n\n<li>We should only use the <em>Defer<\/em> option when the join data is irrelevant to the loop logic. Otherwise, we will get the wrong data.<\/li><\/ol><\/li>\n\n<li>The <em>Always<\/em> option is the slowest, as we expected.<\/li>\n\n<li>The <em>Minimum<\/em> option\u2019s performance is between <em>Always<\/em> and <em>Defer<\/em>.<ol start=\"1\" class=\"wp-block-list\"><li>It tries to keep the mid-loop join data evaluation accurate, as shown in test case 1.<\/li>\n\n<li>However, the more \u201cavoidable join data flush\u201d there is, the more performant it becomes, to the point that it could be comparable to the <em>Defer<\/em> option\u2019s performance (compare results from test cases 1 and 3).<\/li>\n\n<li>This <em>seems<\/em> to be the no-brainer option here, but please don\u2019t quote me on this. Let\u2019s wait for the official documentation that clarifies the behavior before mass adoption.<\/li><\/ol><\/li>\n\n<li>Different operations that rely on relationships have different performance overheads.<ol start=\"1\" class=\"wp-block-list\"><li>Explicitly fetching join data in the script introduces a much bigger performance overhead than related fields displayed on layouts (compare results from test cases 1 and 2).<\/li>\n\n<li>The number of relationships touching the field being updated doesn\u2019t matter much. The number of related records does matter a little bit. This makes sense as the number of related records determines the number of join data that could be fetched (test case 3).<\/li>\n\n<li>Data viewer changes FileMaker\u2019s evaluation\/flush behaviour (bonus test case).<\/li><\/ol><\/li><\/ol><h3 class=\"wp-block-heading has-ast-global-color-2-color has-text-color\" id=\"One-More-Thing\">One More Thing<\/h3><p>Inspired by this <a href=\"https:\/\/the.fmsoup.org\/t\/new-loop-options-in-v20-3\/3804\/4\" target=\"_blank\" rel=\"noreferrer noopener\">thread<\/a>, we could use this new flush option with the <a href=\"https:\/\/youtu.be\/fc0I2HNi2nw?si=UJFnyb9coF4XPBK8\" target=\"_blank\" rel=\"noreferrer noopener\">single-pass-loop technique<\/a> to control the join data flushing behavior of the entire script.<\/p><p>I hope this article sheds some light on this new feature.<\/p>","protected":false},"excerpt":{"rendered":"<p>According to Claris&#8217; FileMaker Pro Release Notes for Version 20.3.1, Flush includes the following three values:1. Always: When setting a field within a loop, the relationship is flushed along with the join data.2. Minimum: When setting a field within a loop, minimal data is flushed.3. Defer: When setting a field within a loop, data and &hellip;<\/p>\n<p class=\"read-more\"> <a class=\"\" href=\"https:\/\/www.directimpactsolutions.com\/en\/new-flush-option-loop-script-step\/\"> <span class=\"screen-reader-text\">New Flush Option for FileMaker&#8217;s Loop Script Step<\/span> Read More &raquo;<\/a><\/p>\n","protected":false},"author":11,"featured_media":16183,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"_uag_custom_page_level_css":"","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":"","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":"set","footnotes":""},"categories":[29],"tags":[],"class_list":["post-16162","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-low-code"],"uagb_featured_image_src":{"full":["https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/12\/iStock-1354745114-min.jpg",2235,1341,false],"thumbnail":["https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/12\/iStock-1354745114-min-150x150.jpg",150,150,true],"medium":["https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/12\/iStock-1354745114-min-300x180.jpg",300,180,true],"medium_large":["https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/12\/iStock-1354745114-min-768x461.jpg",768,461,true],"large":["https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/12\/iStock-1354745114-min-1024x614.jpg",1024,614,true],"1536x1536":["https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/12\/iStock-1354745114-min-1536x922.jpg",1536,922,true],"2048x2048":["https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/12\/iStock-1354745114-min-2048x1229.jpg",2048,1229,true],"woocommerce_thumbnail":["https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/12\/iStock-1354745114-min-300x300.jpg",300,300,true],"woocommerce_single":["https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/12\/iStock-1354745114-min-600x360.jpg",600,360,true],"woocommerce_gallery_thumbnail":["https:\/\/www.directimpactsolutions.com\/wp-content\/uploads\/2023\/12\/iStock-1354745114-min-100x100.jpg",100,100,true]},"uagb_author_info":{"display_name":"Weihao Ding","author_link":"https:\/\/www.directimpactsolutions.com\/en\/author\/weihao-dingdirectimpactsolutions-com\/"},"uagb_comment_info":0,"uagb_excerpt":"According to Claris&#8217; FileMaker Pro Release Notes for Version 20.3.1, Flush includes the following three values:1. Always: When setting a field within a loop, the relationship is flushed along with the join data.2. Minimum: When setting a field within a loop, minimal data is flushed.3. Defer: When setting a field within a loop, data and&hellip;","_links":{"self":[{"href":"https:\/\/www.directimpactsolutions.com\/en\/wp-json\/wp\/v2\/posts\/16162","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.directimpactsolutions.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.directimpactsolutions.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.directimpactsolutions.com\/en\/wp-json\/wp\/v2\/users\/11"}],"replies":[{"embeddable":true,"href":"https:\/\/www.directimpactsolutions.com\/en\/wp-json\/wp\/v2\/comments?post=16162"}],"version-history":[{"count":4,"href":"https:\/\/www.directimpactsolutions.com\/en\/wp-json\/wp\/v2\/posts\/16162\/revisions"}],"predecessor-version":[{"id":19981,"href":"https:\/\/www.directimpactsolutions.com\/en\/wp-json\/wp\/v2\/posts\/16162\/revisions\/19981"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.directimpactsolutions.com\/en\/wp-json\/wp\/v2\/media\/16183"}],"wp:attachment":[{"href":"https:\/\/www.directimpactsolutions.com\/en\/wp-json\/wp\/v2\/media?parent=16162"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.directimpactsolutions.com\/en\/wp-json\/wp\/v2\/categories?post=16162"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.directimpactsolutions.com\/en\/wp-json\/wp\/v2\/tags?post=16162"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}