diff --git a/src/components/abstract_types.jl b/src/components/abstract_types.jl
index 6ef5cb2b30efa1c752b716a08af7c8c484b93926..3aeb6835bf9b5f0634a245fe3786aa5b75677f94 100644
--- a/src/components/abstract_types.jl
+++ b/src/components/abstract_types.jl
@@ -37,10 +37,16 @@ abstract type ReadoutComponent <: EventComponent end
 
 
 """
-    split_times(component, t1, t2, precision)
+    split_timestep(component, precision)
 
-Indicates at what timepoints a given [`BaseComponent`](@ref) should be split during linearisation to achieve the given precision.
+Indicates the maximum timestep that a component can be linearised with and still achieve the required `precision`.
+
+Typically, this will be determined by the maximum second derivative:
+
+``\\sqrt{\\frac{2 \\epsilon}{max(|d^2y/dx^2|)}}``
+
+It should be infinite if the component is linear.
 """
-function split_times end
+function split_timestep end
 
 end
\ No newline at end of file
diff --git a/src/components/components.jl b/src/components/components.jl
index 4fa10355ef9cebd85a7189b78af3a3ec7662af0f..880f6d2986884ecb098ba00b90afa90f98e6555c 100644
--- a/src/components/components.jl
+++ b/src/components/components.jl
@@ -5,7 +5,7 @@ include("instant_gradients.jl")
 include("pulses/pulses.jl")
 include("readouts/readouts.jl")
 
-import .AbstractTypes: BaseComponent, GradientWaveform, EventComponent, RFPulseComponent, ReadoutComponent, split_times
+import .AbstractTypes: BaseComponent, GradientWaveform, EventComponent, RFPulseComponent, ReadoutComponent, split_timestep
 import .GradientWaveforms: ConstantGradient, ChangingGradient, NoGradient, split_gradient
 import .InstantGradients: InstantGradient
 import .Pulses: GenericPulse, InstantPulse, SincPulse, ConstantPulse
diff --git a/src/components/gradient_waveforms/gradient_waveforms.jl b/src/components/gradient_waveforms/gradient_waveforms.jl
index 61c00a053e5bdade108644421a473a46e36fe7cb..bacba79a34069cde77d60a590600fc8febd462e4 100644
--- a/src/components/gradient_waveforms/gradient_waveforms.jl
+++ b/src/components/gradient_waveforms/gradient_waveforms.jl
@@ -21,11 +21,11 @@ include("constant_gradient_blocks.jl")
 include("no_gradient_blocks.jl")
 
 
-import ..AbstractTypes: GradientWaveform, split_times
+import ..AbstractTypes: GradientWaveform, split_timestep
 import .NoGradientBlocks: NoGradient
 import .ChangingGradientBlocks: ChangingGradient, split_gradient
 import .ConstantGradientBlocks: ConstantGradient
 
-split_times(wv::GradientWaveform, t1, t2, precision) = [t1, t2]
+split_timestep(wv::GradientWaveform, precision) = Inf
 
 end
\ No newline at end of file
diff --git a/src/components/pulses/constant_pulses.jl b/src/components/pulses/constant_pulses.jl
index c08db0980c428940e4b73bc9ed35ec495369e8af..f2891a01223a6761e74b272829cd5342d50525b3 100644
--- a/src/components/pulses/constant_pulses.jl
+++ b/src/components/pulses/constant_pulses.jl
@@ -1,6 +1,6 @@
 module ConstantPulses
 import JuMP: @constraint
-import ...AbstractTypes: RFPulseComponent, split_times
+import ...AbstractTypes: RFPulseComponent, split_timestep
 import ....BuildSequences: global_model
 import ....Variables: duration, amplitude, effective_time, flip_angle, phase, inverse_bandwidth, VariableType, set_simple_constraints!, frequency, make_generic, get_free_variable
 import ..GenericPulses: GenericPulse
@@ -61,7 +61,7 @@ function make_generic(block::ConstantPulse)
 end
 
 
-split_times(pulse::ConstantPulse, t1, t2, precision) = [t1, t2]
+split_timestep(pulse::ConstantPulse, precision) = Inf
 
 
 end
\ No newline at end of file
diff --git a/src/components/pulses/generic_pulses.jl b/src/components/pulses/generic_pulses.jl
index 6a5750a1345c82e6e1f9db40e4c4499a3b509b86..8b9f72ea3cb23836f27210900c59a0dbbcc670b7 100644
--- a/src/components/pulses/generic_pulses.jl
+++ b/src/components/pulses/generic_pulses.jl
@@ -1,6 +1,7 @@
 module GenericPulses
 
-import ...AbstractTypes: RFPulseComponent, split_times
+import Polynomials: fit
+import ...AbstractTypes: RFPulseComponent, split_timestep
 import ....Variables: duration, amplitude, effective_time, flip_angle, make_generic, phase
 
 
@@ -78,38 +79,26 @@ end
 
 make_generic(gp::GenericPulse) = gp
 
-function split_times(gp::GenericPulse, t1, t2, precision)
-    real_amplitude_precision = precision * amplitude(gp)
-    real_phase_precision = 180 * precision
-
-    current_index = find(t -> t >= t1, gp.time)
-    final_index = find(t -> t > t2, gp.time)
-    if isnothing(final_index)
-        final_index = length(gp.time)
-    end
-    times = [t1]
-    while gp.time[current_index] < t2
-        current_time = gp.time[current_index]
-        current_amplitude = gp.amplitude[current_index]
-        current_phase = gp.phase(current_index)
-        slope_amplitude = (gp.amplitude[current_index + 1] - current_amplitude) / (gp.time[current_index + 1] - current_time)
-        slope_phase = (gp.phase[current_index + 1] - current_phase) / (gp.time[current_index + 1] - current_time)
-
-        next_index = current_index
-        for next_index in current_index+2:final_index
-            if (
-                abs(slope_amplitude * (gp.time[next_index] - current_time) - gp.amplitude[next_index]) > real_amplitude_precision ||
-                abs(slope_phase * (gp.time[next_index] - current_time) - gp.phase[next_index]) > real_phase_precision
-            )
-                next_index -= 1
-                push!(times, gp.time[next_index])
-                break
+function split_timestep(gp::GenericPulse, precision)
+    function second_derivative(arr)
+        max_second_der = 0.
+        for index in 2:length(arr)-1
+            poly = fit(gp.times[index-1:index+1], arr[index-1:index+1])
+            second_der = abs(poly.coeffs[end])
+            if second_der > max_second_der
+                max_second_der = second_der
             end
         end
-        current_index = next_index
+        return max_second_der
+    end
+    max_second_der = max(
+        second_derivative(gp.amplitude ./ maximum(gp.amplitude)),
+        second_derivative(gp.phase ./ 360),
+    )
+    if iszero(max_second_der)
+        return Inf
     end
-    push!(times, t2)
-    return times
+    return sqrt(2 * precision / max_second_der)
 end
 
 
diff --git a/src/components/pulses/sinc_pulses.jl b/src/components/pulses/sinc_pulses.jl
index fa562c9b91eaf2076b20d2c0942cd482d0bb0597..e5d43bbd3bdf8a52c50150b16959e33b4fe7f17a 100644
--- a/src/components/pulses/sinc_pulses.jl
+++ b/src/components/pulses/sinc_pulses.jl
@@ -3,7 +3,7 @@ import JuMP: @constraint
 import QuadGK: quadgk
 import ....BuildSequences: global_model
 import ....Variables: duration, amplitude, effective_time, flip_angle, phase, inverse_bandwidth, VariableType, set_simple_constraints!, frequency, make_generic, get_free_variable
-import ...AbstractTypes: RFPulseComponent, split_times
+import ...AbstractTypes: RFPulseComponent, split_timestep
 import ..GenericPulses: GenericPulse
 
 """
@@ -101,11 +101,9 @@ function make_generic(block::SincPulse)
     return GenericPulse(times, amplitudes, phases, effective_time(block))
 end
 
-function split_times(block::SincPulse, t1, t2, precision)
+function split_timestep(block::SincPulse, precision)
     max_second_derivative = π^2/3 * (amplitude(block) / lobe_duration(block))^2
-    step_size = sqrt(2 * precision / max_second_derivative)
-    npoints = Int(div(t2 - t1, step_size, RoundUp))
-    return range(t1, t2, length=npoints)
+    return sqrt(2 * precision / max_second_derivative)
 end
 
 end
\ No newline at end of file
diff --git a/src/components/readouts/readouts.jl b/src/components/readouts/readouts.jl
index 45e34327870e438c14194a655ccef9fbdaf586a0..7271159ec7a798abac6c95320408584554531dc7 100644
--- a/src/components/readouts/readouts.jl
+++ b/src/components/readouts/readouts.jl
@@ -2,9 +2,9 @@ module Readouts
 include("ADCs.jl")
 include("single_readouts.jl")
 
-import ..AbstractTypes: ReadoutComponent, split_times
+import ..AbstractTypes: ReadoutComponent, split_timestep
 import .ADCs: ADC, readout_times
 import .SingleReadouts: SingleReadout
 
-split_times(rc::ReadoutComponent, t1, t2, precision) = [t1, t2]
+split_times(rc::ReadoutComponent, precision) = Inf
 end
\ No newline at end of file
diff --git a/src/containers/linearise.jl b/src/containers/linearise.jl
index 5ca43bda44b0116e0cd93943c2c17e043281c9dd..86ac78c38407997c8ab32cf534721631f7625490 100644
--- a/src/containers/linearise.jl
+++ b/src/containers/linearise.jl
@@ -1,6 +1,6 @@
 module Linearise
 import StaticArrays: SVector
-import ...Components: GradientWaveform, split_times
+import ...Components: GradientWaveform, split_timestep
 import ...Variables: amplitude, phase, gradient_strength3, duration
 import ..Abstract: edge_times, start_time, end_time
 import ..BaseSequences: BaseSequence, Sequence
@@ -45,15 +45,18 @@ function linearise(bb::BaseBuildingBlock; precision=0.01)
         tmean = (t1 + t2) / 2
 
         # determine where to split this domain
-        possible_splits = Any[[t1, t2], ]
+        timestep = Inf
         for key in keys(bb)
             if !(start_time(bb, key) < tmean < end_time(bb, key))
                 continue
             end
-            block = bb[key]
-            append!(possible_splits, start_time(bb, key) .+ split_times(block, t1 - start_time(bb, key), t2 - start_time(bb, key), precision))
+            new_timestep = split_timestep(block, precision)
+            if new_timestep < timestep
+                timestep = new_timestep
+            end
         end
-        tsplits = argmax(length, possible_splits)
+        nsteps = div(t2 - t1, timestep, RoundUp)
+        tsplits = range(t1, t2, length=nsteps)
 
         for (t1b, t2b) in zip(tsplits[1:end-1], tsplits[2:end])
             tmeanb = (t1b + t2b) / 2