Why the same execution plan causes LOB reads in some cases?
Comparing the two plans reveal this snippet:

                      &lt;Warnings&gt;
                        &lt;SpillToTempDb SpillLevel="1" /&gt;
                      &lt;/Warnings&gt;


The two plans enter execution with the same memory grant, but one has actual rows 3910 (and spills) while the other has 1502. As far as I can tell, the difference comes from the spatial operator itself. So ultimately the difference in runtime you see comes from the actual spatial data. I can also see that the actual Point you're computing the distance from differs:

          &lt;ColumnReference Column="@Location" ParameterRuntimeValue="POINT (-75.549 39.7366)" /&gt;
          &lt;ColumnReference Column="@Location" ParameterRuntimeValue="POINT (-83.6026 41.6721)" /&gt;


The plan that spills and has more rows to process is the one you labeled 'FAST'. Are you sure you did not mislabeled them? It makes a lot more sense for the spilling one to be slower.